设计:C++中的通用接口配置-reader
Design: A general interface config-reader in C++
我将要设计一个从文件中读取数据的配置-reader。文件中的数据可能是不同的类型,例如 int/float/string ...
希望config-reader界面简洁,方便大家使用。
首先,我列出了所有类型
enum class DataType { INT, UINT32, UINT64, FLOAT, STRING, ARRAY, USER_TYPE, BADTYPE };
然后,我写了 "base" class for all types
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()
之后,我们得到一个指向其派生 class 的 BasicType 指针。这里我想恢复原来的派生class。 "conversion"有什么好办法吗?或者是否有更好的方法来解决这个问题?
谢谢!
Here I want to recover the orignal derived class.
if (const IntType* p = dynamic_cast<const IntType*>(b))
do something with p->value_int;
else ...
if there're any better ways for this problem?
很难说,如果没有您的 robustness/performance/memory-usage 等要求的背景,为什么您不将它们存储在读取时的实际类型中(即类型安全 "deserialisation"),为什么你不使用现有的库等。无论如何,在类似的 space 中,你可能想 Google 获取 boost::variant
and/or boost::lexical_cast
上的文档 -他们可以帮助类似 storage/conversions.
我将要设计一个从文件中读取数据的配置-reader。文件中的数据可能是不同的类型,例如 int/float/string ...
希望config-reader界面简洁,方便大家使用。
首先,我列出了所有类型
enum class DataType { INT, UINT32, UINT64, FLOAT, STRING, ARRAY, USER_TYPE, BADTYPE };
然后,我写了 "base" class for all types
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()
之后,我们得到一个指向其派生 class 的 BasicType 指针。这里我想恢复原来的派生class。 "conversion"有什么好办法吗?或者是否有更好的方法来解决这个问题?
谢谢!
Here I want to recover the orignal derived class.
if (const IntType* p = dynamic_cast<const IntType*>(b))
do something with p->value_int;
else ...
if there're any better ways for this problem?
很难说,如果没有您的 robustness/performance/memory-usage 等要求的背景,为什么您不将它们存储在读取时的实际类型中(即类型安全 "deserialisation"),为什么你不使用现有的库等。无论如何,在类似的 space 中,你可能想 Google 获取 boost::variant
and/or boost::lexical_cast
上的文档 -他们可以帮助类似 storage/conversions.