用不同的返回类型覆盖基类函数

Posted

技术标签:

【中文标题】用不同的返回类型覆盖基类函数【英文标题】:Overriding a base class function with different return types 【发布时间】:2013-10-06 13:19:26 【问题描述】:

我有一个名为变量的基类:

class Variable

protected:
    std::string name;   
public:
    Variable(std::string name="");
    Variable (const Variable& other);
    virtual ~Variable();
;

我有几个派生类,例如 Int、Bool、String 等。例如:

class Bool: public Variable
private:
    bool value;

public:
    Bool(std::string name, bool num);
    ~Bool();
    Bool (const Bool& other);
    bool getVal();

每个派生类都有一个名为 getVal() 的方法,该方法返回不同的类型(bool、int 等)。我想允许变量类的多态行为。 我试过:void getVal(); 这似乎是错误的,编译器显示错误:shadows Variable::getVal() 这听起来很糟糕。 我想过使用template <typename T> T getVal();,但没有帮助。

有什么建议吗?我必须为此使用强制转换吗?

非常感谢...

【问题讨论】:

显示您在基类和派生类中尝试的内容 Variable condition = condition_statement.evaluate(type); //condition_statement.evaluate(type) 返回一个 Bool 对象 cout << condition.getval(); 编译器说:“‘类变量’没有名为‘getVal’的成员” 请注意,您只能拥有 协变返回类型,而覆盖函数,否则您最终会隐藏基类函数,这不是您想要的行为。 cout 应该如何知道要打印什么类型? 这只是一个例子...condition.getVal() 应该返回布尔值。但它也可以是字符串、int 或 folat。这取决于对象的类型。 Bool 的 getVal() 返回 bool,Int 的 getVal() 返回 int 等。我希望能够在类变量中创建方法 getVal(),该方法将被派生类的 getVal() 覆盖。 【参考方案1】:

你can't overload by return type。我认为模板在您的情况下会更好。这里不需要多态或继承:

template<class T>
class Variable 
protected:
    T value;
    std::string name;   
public:
    Variable(std::string n, T v);
    Variable (const Variable& other);
    virtual ~Variable();
    T getVal();
;

用法是pretty simple:

Variable<bool> condition("Name", true);
Variable<char> character("Name2", 'T');
Variable<unsigned> integer("Name3", 123);
std::cout << condition.getVal() << '\n';
std::cout << character.getVal() << '\n';
std::cout << integer.getVal() << '\n';

【讨论】:

谢谢。但我需要不同的派生类(例如 Bool、String、Int、Float 等)具有不同的运算符重载行为。假设我需要 Int 覆盖 operator+ 并最终添加值,但如果尝试 Bool+Bool ,则 Bool 应该抛出异常。如何使用模板做到这一点? @Shakedk,这不是问题。只需使用template specialization。 看起来有点复杂,但我会试一试。谢谢!【参考方案2】:

类型在编译时确定。因此,再多的多态性也不允许您更改返回类型。 虚拟调度是在运行时完成的,但方法和对象的类型必须正确,并且在编译时必须相同。

如果只需要打印值,只需添加虚拟 ToString() 方法即可。如果您不想为每个派生类型再次编写它,甚至可以将 i 模板化。

【讨论】:

以上是关于用不同的返回类型覆盖基类函数的主要内容,如果未能解决你的问题,请参考以下文章

C++之重载覆盖和隐藏

比较Java方法的重载与覆盖

java-协变返回类型

java-协变返回类型

覆盖虚函数协变返回类型(两个指针)

c++部分面试题