-1

基类:

class Base
{
    public:
        virtual int f() const
        {
            return 1;
        }
};

派生类:

class Derived: public Base
{
    public:
        void f() const {}
};

上面的代码抛出“返回类型不相同/协变错误”。

我读过一些关于它的讨论。这个类似,但他们只说如果返回类型不同/协变,它将破坏代码。 覆盖具有不同返回类型的成员函数

为什么我期望的行为没有发生?

预期行为: Derived 中的 VPTR 指向 Base::f() (我读过如果没有为虚函数提供覆盖,Derived 对象将只使用继承的类版本)。它还隐藏了名称 f() 所以现在这样的调用:

Derived x;
x.f();

应该调用 Derived::f() 和这样的调用:

x.Base::f();

应该调用 Base::f() 函数。这似乎不像破坏代码。万一它被升级了,即使那样它也不应该破坏代码,因为两个类的 VPTR 都指向同一个 Base::f()

我能想到的唯一原因是这样的声明(相同的签名和协变/相同的返回类型)被保留用于覆盖虚拟方法,我们不能使用它来导致我期望的行为。

4

1 回答 1

0

当编译器遇到匹配的签名(参数、常量)时,它会自动使void f() const声明成为虚拟的。所以 的定义Derived被解释为:

class Derived: public Base
{
    public:
        virtual void f() const {} // virtual keyword is added
};

它显然看起来像是试图覆盖Base::f(). 所有这一切都是因为函数签名在BaseandDerived类中匹配。如果签名不匹配,那么这只会是重新定义,在这种情况下它会隐藏类Base::f()中的Derived

于 2021-06-07T03:43:57.727 回答