C++:没有指针的协变返回类型

Mon*_*onk 2 c++ pointers covariant-return-types

我通过继承创建了两个简单的类,并在子类中添加了一个虚函数和覆盖.

class Parent
{
public:
    virtual Parent foo();
};

class Child : public Parent
{
public:
    Child foo() override;
};
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我的重写函数会出错: error C2555: 'Child::foo': overriding virtual function return type differs and is not covariant from 'Parent::foo'

如果我用指针更改返回类型:

class Parent
{
public:
    virtual Parent* foo();
};

class Child : public Parent
{
public:
    Child* foo() override;
};
Run Code Online (Sandbox Code Playgroud)

错误消失了!我不明白为什么返回类型的协方差必须用指针完成,我不能使用值类型或引用.一些网站或论坛解释说,因为返回的值是函数中使用的值的副本,编译器知道指针的常量大小,但必须指示被覆盖函数和父函数的不同大小,这显然是不可能的.

那么,为什么我不能在这种情况下使用除指针之外的任何东西呢?如果我希望子类型在不使用指针的情况下键入重写函数,那么我必须为每个函数返回基类并将返回的类型转换为子类型吗?

Sto*_*ica 5

协变返回类型的概念是多态返回类型.而在C++中,没有指针或引用就不能有运行时多态性.让我们忽略了大部分的艰辛,并假装它是可能的.这是我的代码,通过您的Parent界面处理事物:

void bar(Parent * p) {
  auto o = p->foo();
}
Run Code Online (Sandbox Code Playgroud)

什么是o?嗯,这Parent当然是.在Parent::foo回归类型中说的如此.但如果那p指的是Child什么呢?推断的类型o仍然是Parent,所以充其量我得到一个切片的对象.没有多态行为,所以整个练习毫无意义.

在最坏的情况下,我很可能会得到未定义的行为.

这就是为什么共变量返回类型必须是指针或引用.