为什么在虚函数声明中使用不同的 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()
。所有这一切的发生是因为 Base
和 Derived
class 中的函数签名匹配。如果签名不匹配,那么这只是一个重新定义,在这种情况下它会隐藏 Derived
class.
中的 Base::f()
基础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()
。所有这一切的发生是因为 Base
和 Derived
class 中的函数签名匹配。如果签名不匹配,那么这只是一个重新定义,在这种情况下它会隐藏 Derived
class.
Base::f()