我正在为一个应该包含值的对象创建一个类,但是该值将以VALUE,DATATYPE的形式从外部读取,其中DATATYPE告诉我如何解释给定的VALUE(int,float,double ,char等)。
我想知道是否有可能在运行时进行投射以及如何进行投射,说实话我有点迷失,而且我发现的有关该主题的信息似乎有点过分。
有什么想法吗?感谢。
答案 0 :(得分:1)
特别是查找有区别的联盟和boost :: variant,但要点是:
struct Value {
enum { INT, FLOAT, DOUBLE, CHAR, ETC } type;
union {
int int_;
float float_;
double double_;
char char_;
etc etc_;
} value;
};
然后在执行任何操作之前检查类型,并根据存储在其中的内容选择正确的联合成员。
答案 1 :(得分:1)
我会为每种类型创建一个“解析器”地图。解析器可以是指向接受字符串并返回变量的函数的指针(请参阅其他答案)。像这样(未经测试的伪代码):
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);
}
}
无效的变体我的意思是一种不包含任何东西的特殊类型。它也可以被称为空变量或空变量。正如评论中所指出的,解析器字段也可以是静态的,但是它应该以某种静态方式初始化。例如,它可以封装在另一个具有默认构造函数的类中。
答案 2 :(得分:0)
您所描述的是变体类型。开始阅读here。
您可以创建一个从文件中读取数据的类,并将其内部存储在变体中。
答案 3 :(得分:0)
最具扩展性的是抽象工厂模式。
typedef boost::function<Variant(istream&)> VariantFactory;
std::map< int, VariantFactory > variantFactoryTable;
Variant readVariantFromStream(istream& is)
{
int type = 0;
if( is >> type )
{
std::map<int, VariantFactory>::const_iterator factIter =
variantFactoryTable.find(type);
if(factIter != variantFactoryTable.end() )
{
return factIter->second(is);
}
else
{
// handle error by throwing or returning a Null
}
}
else
{
// handle EOS condition (probably not with exception)
}
}