我即将设计一个从文件中读取数据的配置阅读器。文件中的数据可能是不同的类型,如int / float / string ...
我希望配置阅读器具有简单的界面,以便人们可以轻松使用它。
首先,我写了列出所有类型
enum class DataType { INT, UINT32, UINT64, FLOAT, STRING, ARRAY, USER_TYPE, BADTYPE };
然后,我为所有类型编写了“基础”类
class BasicType{
public:
DataType value_type;
public:
BasicType() : value_type(DataType::USER_TYPE){}
virtual bool parse(const string& ) {}
virtual string toString(){ return ""; }
};
然后,我继续编写每个特定类型的实现,比如
template <int _type>
class BuildInType: public BasicType
{
private:
// TODO replace this with boost variant or so
int value_int;
uint32_t value_uint32;
uint64_t value_uint64;
float value_float;
string value_string;
public:
BuildInType() {
value_type = static_cast<DataType>(_type);
}
void bool parse(const string& data_field){ ... }
};
typedef BuildInType < static_cast<int>(DataType::INT) > IntType;
typedef BuildInType < static_cast<int>(DataType::UINT32) > Uint32Type;
typedef BuildInType < static_cast<int>(DataType::UINT64) > Uint64Type;
...
这里让我们忘记Array-type和USER-Defined类型
对于界面,
class Parser{
...
BasicType* read_next(){
//The parse will read the data from file
//and return something like &IntType, &FloatType or so
};
Parser p("some file");
while(true){
BasicType* b = p.read_next();
if(!b)break;
// Here I'm trying to convert BaseType back to IntType/FloatType etc,
// because I want to fetch value_int/value_float ... defined in these derived-classes
}
在read_next()
之后,我们得到一个指向其派生类的BasicType指针。在这里,我想恢复orignal派生类。有什么好方法可以进行“转换”吗?或者,如果有更好的方法解决这个问题?
谢谢!
答案 0 :(得分:0)
这里我想恢复原始派生类。
if (const IntType* p = dynamic_cast<const IntType*>(b))
do something with p->value_int;
else ...
如果有更好的解决方法吗?
很难说没有关于您的稳健性/性能/内存使用等要求的背景知识,为什么您不会将它们存储在实际类型中(因为它们被读取)(即类型安全&#34) ;反序列化&#34;),为什么你不使用现有的库等等。无论如何,在类似的空间中,你可能希望谷歌在boost::variant
和/或boost::lexical_cast
上使用文档 - 他们可以对类似的存储/转换有所帮助。