【问题标题】:Derived Class of Abstract Base Class does not correctly override Base pure virtual method抽象基类的派生类未正确覆盖基纯虚方法
【发布时间】:2019-08-31 03:15:48
【问题描述】:

所以我试图创建一个抽象基类的派生类,但是不能使用派生类声明纯虚方法。

template<class T>
class Foo
{
    public:
        virtual Foo<T>* add(const Foo<T>* rhs) = 0; 
};

template<class T>
class Doo : public Foo<T>
{
    public:
        Doo<T>* add(const Doo<T>* rhs)
        {
            return this;
        }
};

int main()
{
    Doo<double> d;
    return 0;
}

我希望 Doo 中的 add 方法声明能够工作,因为 Doo 是 Foo 的子类,但是 g++ 说我没有覆盖 Foo's add 方法。我假设这对我声明Doo's add 方法的方式很简单。

【问题讨论】:

  • 一个取一个Foo另一个取一个Doo,这些是不同的方法

标签: c++ inheritance abstract-class


【解决方案1】:

签名不匹配,因此您不会覆盖任何内容。查找 override 关键字,让您的编译器帮助您诊断此类错误。

add(const Foo<T>* rhs)

不一样

add(const Doo<T>* rhs)

他们采取不同的论点。

它们还返回不同的类型。但是返回类型在重载决议或覆盖时并不重要,但这通常也表明您缺少标记(您想要覆盖的标记),因为通常您希望您的覆盖函数返回与它覆盖的类型相同。

【讨论】:

  • 我看到这可以解决问题,但我担心从 Foo 派生的任何其他类都可以传递给这个方法。是确保继承对象不违反父要求的唯一解决方案吗?
  • @evader110 抱歉,我不太清楚你在问什么。
  • 如果我从Foo 派生了另一个名为Goo 的派生类,如果我将它传递给Doo 的add 方法,它会起作用吗?如果是这样,在 Doo 中创建一个非虚拟方法是避免这种行为的唯一方法吗?
  • @evader110 通过声明一个纯虚拟的add 方法,Foo 承诺所有派生类都将有一个add 方法,该方法接受指向Foo 的指针。对其参数施加任何额外限制的add 方法不履行该承诺,因此不被视为该纯虚方法的实现。
【解决方案2】:

通过使用具有不同签名的函数,您隐藏了该函数而不是覆盖它。

保护自己免受这些错误影响的最佳方法是在每次打算重写虚函数时使用override 关键字,如下所示(在您的示例中):

Doo<T>* add(const Doo<T>* rhs) override

如果函数实际上没有覆盖,编译器会报错。

【讨论】:

    猜你喜欢
    • 2020-08-01
    • 1970-01-01
    • 2019-02-07
    • 2011-06-01
    • 2018-08-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-19
    • 1970-01-01
    相关资源
    最近更新 更多