用不同的 return 类型覆盖虚函数

Override virtual function with different return type

我知道如果 return 类型是协变的,可以使用 return 类型覆盖虚函数。

但是我们可以使用更改后的 return 类型吗?或者 return 类型将隐式转换为基本 class 函数的 return 类型,例如 B*A* 此处。

class A
{
    public:
    virtual A *func()
    {
        A *obj=0;
        return obj;
    }
};

class B:public A
{
    public:
    virtual B *func()
    {
       B *obj =0;
       return obj;
    }
};

int main()
{
    A *obj = new B();
    obj->func();              // does in fact call B::func()
    B *obj2 = obj->func();    // throws error: invalid conversion from 'A*' to 'B*'

    return 0;
}

似乎 obj->func() 是 returning A* 而不是 B*,因此我得到这个转换错误。

静态类型检查必须仍然有效,即使动态类型在实现中做了一些稍微不同的事情。所以它真的取决于所指向对象的静态类型。当您在 A* 上调用虚拟成员时,return 类型被指定为 A*.

如果您要在 B* 上调用它,函数的 return 类型将是(静态)B*

B *obj = new B();
obj->func();              
B *obj2 = obj->func();   // Okay now

每当你在 C++ 中处理 运行 时间多态性时,确定接口的是对象的 静态类型

obj 的静态类型是 A* 所以 obj->func() 会使用 A *A::func() 声明:

  • return 类型 (A*)
  • 访问说明符(public:
  • 默认参数 (n/a)

动态类型是 B*,所以它会调用 B* B::func() 并且由于协变类型实际上会在 A*.[=19= 中转换它的 return 值]

继承层次结构中的类型可以隐式向下转换,在您的示例中从 BA,这也允许协变 return 类型。但是你尝试隐式向上转换,

B *obj2 = obj->func();

无法工作,因为 obj 是一个 A 实例,并且 func() 静态绑定到 A 提供的签名。如果必须从 A::func() 获得 B*,您可以使用显式转换

auto *obj2 = dynamic_cast<B*>(obj->func());

但这是一种糟糕的模式,因为它损害了多态性的全部意义。