设计: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.