覆盖具有不同返回类型的成员函数

nit*_*ian 21 c++ overriding virtual-functions redefinition

考虑以下示例:

#include <iostream>

using namespace std;

class base
{
   public:
      virtual int func()
      {
         cout << "vfunc in base class\n";
         return 0;
      }
};

class derived: public base
{
   public:
      double func()
      {
         cout << "vfunc in derived class\n";
         return 0;
      }
};

int main()
{
   base *bptr = new derived;
   bptr->func();

   return 0;
}
Run Code Online (Sandbox Code Playgroud)

编译器为上面的代码提供了一个错误,即覆盖函数存在冲突类型.为什么不能使用不同的返回类型覆盖派生类中的函数?

我相信,为了覆盖一个函数,需要在派生类中重新定义基类虚方法.要重新定义方法,方法的签名必须相同.由于返回类型不是签名的一部分,我相信即使返回类型有差异,该方法仍将被重新定义?在上述代码的情况下,func在派生类中使用不同的返回类型重新定义虚函数.但是编译器会抛出错误.我的理解是否正确?

Alo*_*ave 24

覆盖本质上意味着将在运行时调用Base类方法或Derived类方法,具体取决于指针指向的实际对象.
它意味着:
ie:可以通过调用Derived类方法替换可以调用Base类方法的每个地方,而不需要对调用代码进行任何更改.

为了实现这一点,唯一可能的方法是限制重写虚方法的返回类型以返回与Base类相同的类型或从该类派生的类型(共变量返回类型),并且Standard强制执行此条件.

如果上述条件不存在,它将留下一个窗口,通过添加新功能来破坏现有代码.

  • Als:`类型派生自(共变型返回类型)`.这对我的理解至关重要.很好的解释.:) (4认同)

bdo*_*lan 12

为了覆盖虚函数,返回值必须完全相同*.C++ 不会在这里doubleint这里之间自动转换- 毕竟,从派生类指针调用时,它如何知道你想要的返回类型?请注意,如果更改部分签名(参数,常量等),则还可以更改返回值.

* - 严格来说,它必须是'协变'.这意味着您返回的类型必须是父函数返回类型的子集.例如,如果父类返回a base *,则可以返回a derived *.由于deriveds同时也是bases,编译器允许您以这种方式覆盖.但你不能回归完全不相关的类型,如intdouble; 只是因为有隐式转换并不意味着编译器会让你做这种覆盖.

  • 我认为你的意思完全相同或是一个子类. (3认同)

ezo*_*zod 6

看到这个问题.总而言之,如果类型是协变的,则只能使用不同的返回类型覆盖虚函数.