具有不同返回类型的C++多态函数

C++ polymorphic functions with differing return types

本文关键字:C++ 多态 函数 返回类型      更新时间:2023-10-16

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

(顺便说一句,我回避模板,因为我使用的是Qt,它所需的接口宏不支持模板化对象。如果值得使用模板,我可能会放弃使用接口的想法。)

我的意图是通过从基属性类中对多个不同类型的属性(string、int、float…)进行子类化,并允许基属性指针数组,从而允许它们的列表。然而,我遇到了这样一个问题,即从其中一个派生类中将属性提取为特定类型会变得非常困难,因为指向基类的指针显然不知道派生类中新定义的getValue函数。我只能选择从基类中提取字符串并手动转换,或者将基类指针强制转换为正确的派生类指针。第一个选项要求我手动进行转换,从而使子类化变得毫无用处。第二个选项听起来像是代码的噩梦,因为每次我想计算出要转换到哪个指针时,属性标识符值上都会涉及一个大的switch语句。

解决这个问题最明智的方法是什么?我想让属性值的检索尽可能简单——也就是说,尽可能少地使用样板代码,从从数组中获取基类指针到保存属性值的正确类型副本。如果有多个强类型属性类,它们都支持使用字符串获取和设置各自的值,那么换一种方式考虑这个问题是否值得?

这个怎么样?(未经测试,但你应该明白)

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

当然,因为接收方需要知道它得到的是什么类型,所以使用一个指示你得到什么的名称,例如

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

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