3

我正在创建一个属性类,它将唯一键和任意值存储为字符串(加上一个可选的注释字符串,用于写入配置文件时使用)。目前我正在使用创建一个包含原始字符串的基本属性类的方法,然后将其子类化为特定于类型的属性 - 例如。一个 IntProperty,它实现了一个将字符串转换为 int 的 getValue() 函数——以避免每次我想读取它时都必须从字符串手动转换属性值。这些子类使用 getPropertyType(),一个在基类中定义并在每个派生类中重写的虚函数,返回一个枚举值来标识它们持有的属性类型,而基类返回一个“无”标识符。

(作为旁注,我避开了模板,因为我使用的是 Qt 并且它所需的接口宏不支持模板化对象。如果值得使用模板,我可能会放弃使用接口的想法。)

我的意图是通过从基属性类继承它们并允许基属性指针数组来允许多个不同类型的属性(字符串、int、float ...)的列表。但是,我遇到的问题是,从派生类之一中将属性提取为特定类型变得非常尴尬,因为指向基类的指针显然不知道派生类中新定义的 getValue 函数。我可以选择从基类中提取字符串并手动转换,或者将基类指针转换为正确的派生类指针。第一个选项要求我手动进行转换,从而使子类化变得无用,而第二个选项听起来像是一场噩梦,因为那里'

解决这个问题的最聪明的方法是什么?我想尽可能简单地检索属性值 - 即。从从数组中获取基类指针到保存属性值的正确类型的副本,我可以使用尽可能少的样板代码。是否值得反过来考虑这个问题 - 有多个强类型属性类,它们都支持使用字符串获取和设置它们各自的值?

4

2 回答 2

2

当然,由于接收方需要知道它得到什么类型,所以使用一个表明你得到什么的名称,例如

int GetInt(const string& key);
string GetString(const string& key);
double GetDouble(const string& key); 

等将与调用它一样好Get(const string& key)- 而且由于 C++ 语言不允许您仅区分返回类型,因此这是行不通的。

另一种选择当然是有一个

template <typename T>
void Get(const string& key, T& value);

(可能需要以不同的方式实际实现所有不同的变体,因此使用模板可能没有太大帮助,但我更容易将答案作为模板写出来!;))

于 2013-07-03T22:00:23.253 回答
2

那这个呢?(未经测试,但你应该明白)

class BaseType {
public:
    virtual void getValue(string &s) { s = "";                            };
    virtual void getValue(int &i)    { i = 0;                             };
    virtual void getValue(double &d) { d = 0.0;                           };
};

class IntType : public BaseType {
public:
    virtual void getValue(string &s) { s = to_string(myvalue);            };
    virtual void getValue(int &i)    { i = myvalue;                       };
    virtual void getValue(double &d) { d = static_cast<double>(myvalue);  };
private:
    int myvalue;
};

class DblType : public BaseType {
public:
    virtual void getValue(string &s) { s = to_string(myvalue);            };
    virtual void getValue(int &i)    { i = static_cast<int>myvalue;       };
    virtual void getValue(double &d) { d = myvalue;                       };
private:
    double myvalue;
};

class StrType : public BaseType {
public:
    virtual void getValue(string &s) { s = myvalue;                       };
    virtual void getValue(int &i)    { i = stoi(myvalue);                 };
    virtual void getValue(double &d) { d = stod(myvalue);                 };
private:
    string myvalue;
};
于 2013-07-03T23:29:27.140 回答