为什么在虚函数声明中使用不同的 return 类型会引发错误而不是导致重新定义?

Why using a different return type in virtual function declaration throws an error instead of resulting in a redefinition?

基础class:

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

派生 class:

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

以上代码抛出“return 类型不是 identical/covariant 错误”。

我读过一些关于它的讨论。这个很相似,但他们只说如果 return 类型不是 identical/covariant ,它将破坏代码。 Override a member function with different return type

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

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

Derived x;
x.f();

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

x.Base::f();

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

我能想到的唯一原因是这样的声明(相同的签名和 covariant/identical return 类型)是为覆盖虚拟方法而保留的,我们不能用它来引起我的行为期待中。

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

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

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

中的 Base::f()