繁体   English   中英

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

[英]C++ : Covariant return type without pointer

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

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

class Child : public Parent
{
public:
    Child foo() override;
};

在这种情况下,我的重写函数得到一个错误: 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;
};

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

那么,为什么在这种情况下我不能使用指针以外的任何东西? 如果我想在重写函数中使用子类型而不使用指针,是否必须返回每个函数的基类并将返回的类型转换为子类型?

协变返回类型的想法是多态返回类型。 而在 C++ 中,没有指针或引用,你就不可能有运行时多态性。 让我们暂时忽略大部分困难,并假装这是可能的。 这是我通过Parent接口处理事物的代码:

void bar(Parent * p) {
  auto o = p->foo();
}

什么是o 嗯,当然是Parent Parent::foo的返回类型中是这样说的。 但是如果那个p指向一个Child呢? o的推导类型仍然是Parent ,所以我最多得到一个切片对象。 没有多态行为,所以整个练习毫无意义。

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

这就是为什么协变返回类型必须是指针或引用。

这是因为派生类型会返回一个派生实例,但调用者会期待一个父对象,这与使用指针时不同,在指针情况下,派生指针可以滑入为父指针保留的空间,但相同的是谈论实际情况时并非如此。 您还有一个问题,派生方法会返回派生实例,但使用父指针的调用者对此一无所知,因此可能只会破坏父部分。

你会发现很有帮助

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM