首页 > 解决方案 > 如何使用被覆盖函数中的子类引用覆盖纯虚函数

问题描述

所以我在派生类中覆盖纯虚函数时遇到了问题。类的实现和声明如下所示:

class Base{
private:
   size_t id;
public:
   virtual bool isEqual(const Base& src) const =0;
};

class Derived: public Base{
private:
    string str;
public:
    virtual bool isEqual(const Derived& src) const override
    {
        return (this->str == src.str);
    }
};

所以当我像这样实现它时,它会遇到编译器错误,比如

member function declared with 'override' does not override a base class member function

您能否告诉我如何才能做到这一点,也许可以解释一下为什么我的版本不起作用。提前致谢!

标签: c++overridingabstract-classvirtual-functions

解决方案


您不能以这种方式更改函数签名 - 阅读有关协变和逆变的详细信息以及为什么 C++ 不允许函数参数同时使用两者(允许协变返回类型)。

另一方面,如果通过对基的引用来引用另一个对象,则根本不会调用覆盖(实际上:重载!)函数:

Derived d1;
Derived d2;
Base& b2 = d2;

d1.isEqual(b2); // how do you imagine the derived version to get called now???

解决方案的关键是dynamic_cast

struct Base
{
    virtual ~Base() { }
    virtual bool operator==(Base const& other) = 0;
};

struct Derived : Base
{
    bool operator==(Base const& other) override
    {
        auto o = dynamic_cast<Derived const*>(&other);
        return o && o->str == this->str;
    }
};

请注意,我将函数重命名为operator==; 这在 C++ 中要自然得多。这样,您可以在上面的示例中与以下示例进行比较:

bool isEqual = d1 == b2;

编辑

老师告诉我们不能重载操作符

好吧,那么只需恢复重命名...实际上,运算符与其他任何函数一样普通函数,只是调用语法不同(实际上:存在替代变体,您也可以始终调用 as d1.operator ==(d2))。


推荐阅读