私は値を含むべきオブジェクトのクラスを作っていますが、値はVALUE、DATATYPEの形で外部的に読み込まれます。ここでDATATYPEは与えられたVALUE(int、float、double、チャー、等)。C++でファイルからデータ型を定義する方法は?
ランニング時にキャスティングを行うことが可能かどうか、正直なところ私は少し失われていると思いますが、トピックについて見つかった情報はちょっとした過労。
アイデア?ありがとう。
私は値を含むべきオブジェクトのクラスを作っていますが、値はVALUE、DATATYPEの形で外部的に読み込まれます。ここでDATATYPEは与えられたVALUE(int、float、double、チャー、等)。C++でファイルからデータ型を定義する方法は?
ランニング時にキャスティングを行うことが可能かどうか、正直なところ私は少し失われていると思いますが、トピックについて見つかった情報はちょっとした過労。
アイデア?ありがとう。
ルックアップは、労働組合を区別し、後押し::バリアントを、特に、しかし要旨は次のとおりです。
struct Value {
enum { INT, FLOAT, DOUBLE, CHAR, ETC } type;
union {
int int_;
float float_;
double double_;
char char_;
etc etc_;
} value;
};
次にあなたが何らかの操作を行う前に型をチェックし、格納されているものに基づいて右の組合員を選択しますその中に。
説明しているのはバリアント型です。 hereを読み始めます。
ファイルからデータを読み込んで内部的にバリアントに格納するクラスを作成できます。
私は、それぞれの種類の "パーサー"のマップを作成したいと思います。パーサーは、文字列を受け取り、バリアントを返す関数へのポインタです(他の回答を参照)。このようなもの(テストされていない疑似コード):
class TypedReader {
public:
typedef Variant (*Parser)(const std::string &value);
Variant readVariant(std::istream &in);
private:
std::map<std::string, Parser> parsers;
// these parsers are added to the "parsers" field above by the constructor
static Variant intParser(const std::string &value);
static Variant doubleParser(const std::string &value);
// and so on
};
Variant TypedReader::readVariant(std::istream &in) {
// read next (type, value) pair
std::map<std::string, Parser>::iterator i = parsers.find(type);
if (i == parsers.end()) {
// error, type not supported, throw exception or return an invalid variant
} else {
return (*i->second)(value);
}
}
無効なバリアントとは、何も含まれていない特殊なタイプを意味します。これは、空のバリアントまたはヌルバリアントとも呼ばれます。コメントで指摘されているように、パーサフィールドも静的にすることができますが、静的な方法で初期化する必要があります。たとえば、デフォルトコンストラクタを持つ別のクラスにカプセル化することができます。
最も拡張性が高いのは、抽象的な工場パターンです。
識別キーが固定されている場合、パーサー・メンバーも静的にすることができます。 「無効なバリアント」とは、バリエーションにもう1つの潜在的な型を追加して、この(有効な)状態を表すことを意味します(私の答えの列挙型に「INVALID」を追加するなど)。しかし、この状態が不要な場合は例外をスローする方が良いでしょう。 –
@Fred、無効な変種はあなたの言ったとおりです。例外は、移植性が少し劣ります。そうでない場合は、通常より優れています。無効なバリアントには、NULLポインタの使用に似た、他の用途もあります。新しいタイプの動的登録をサポートするクラスの1つの後にこのサンプルをモデリングしていたので、パーサーのメンバーは静的である可能性があります。 –