2013-07-03 48 views
2

我正在创建一个属性类,它将唯一键和任意值存储为字符串(以及写入配置文件时使用的可选注释字符串)。目前我正在使用创建基本属性类的方法来保存原始字符串,然后将其分类为特定于类型的属性 - 例如。一个IntProperty,它实现了一个将字符串转换为int的getValue()函数 - 以避免每次我想读取它时都必须从字符串手动转换属性值。这些子类使用getPropertyType(),这是一个在基础中定义并在每个派生中重写的虚函数,用于返回枚举值以标识它们所持有的哪种类型的属性,并且基类返回“none”标识符。因为我使用的是Qt,并且它所需的接口宏不支持模板对象,所以如果值得使用模板,我可能会忽略使用接口的想法。)具有不同返回类型的C++多态函数

(http://support.microsoft.com/kb/

我的目的是通过从基本属性类中继承它们并允许基本属性指针的数组来允许多种不同类型的属性(字符串,整型,浮点...)的列表。然而,我遇到了这样的问题:从派生类中的某个特定类型提取属性会变得非常尴尬,因为指向基类的指针显然不知道派生类中新定义的getValue函数。我剩下的选项是从基类中提取字符串并手动转换,或者将基类指针转换为正确的派生类指针。第一个选项通过要求我手动进行转换来使子类化变得无用,而第二个选项使得子类化成为无用的,而第二个选项使得代码变得无用,因为每次我想知道哪个指针指向哪个指针时,会在属性标识符值中包含一个大的switch语句投到。

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

回答

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; 
}; 
+0

这是一个很好的方法。最终,我选择使用visitor方法,将访问者对象传递给基类指针将返回数据作为访问者中包含的正确类型。 – x6herbius

0

当然,由于接收方需要知道它得到的是什么类型,使用一个表示你回来的名字,例如,

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); 

(可能需要实际执行各种不同的变型的不同,所以它可能不会真正帮助很多使用模板,但它让我更容易写在答案作为模板!))

相关问题