简体   繁体   English

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

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

I create two simple classes by inheritance, and I add a virtual function and the override in the child class.我通过继承创建了两个简单的类,并在子类中添加了一个虚函数和覆盖。

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

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

In this case, my overridden function get an error : error C2555: 'Child::foo': overriding virtual function return type differs and is not covariant from 'Parent::foo'在这种情况下,我的重写函数得到一个错误: error C2555: 'Child::foo': overriding virtual function return type differs and is not covariant from 'Parent::foo'

If I change return types with pointer :如果我使用指针更改返回类型:

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

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

the error gone !错误消失了! I don't understand why the covariance of return types must be done with pointer and I can't use value type or a reference.我不明白为什么返回类型的协方差必须用指针来完成,我不能使用值类型或引用。 Some website or forums explain that because the returned value is a copy of the value used in the function, the compiler know the constant size of a pointer, but must indicate different size for the overridden function and the parent function, which is apparently impossible.一些网站或论坛解释说,由于返回值是函数中使用的值的副本,编译器知道指针的常量大小,但必须为覆盖函数和父函数指示不同的大小,这显然是不可能的。

So, why can't I use anything else than pointer in this case ?那么,为什么在这种情况下我不能使用指针以外的任何东西? If I want the child type in the overridden function without using pointers, must I return the base class for each functions and cast the returned type into the child type ?如果我想在重写函数中使用子类型而不使用指针,是否必须返回每个函数的基类并将返回的类型转换为子类型?

The idea of a covariant return type is a polymorpihc return type.协变返回类型的想法是多态返回类型。 And in C++, you can't have run time polymorphism without pointers or references.而在 C++ 中,没有指针或引用,你就不可能有运行时多态性。 Let's ignore for a second most of the hardships, and pretend it's possible.让我们暂时忽略大部分困难,并假装这是可能的。 Here is my code that handles things by your Parent interface:这是我通过Parent接口处理事物的代码:

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

What is o ?什么是o Well, it's Parent of course.嗯,当然是Parent Says so in Parent::foo 's return type.Parent::foo的返回类型中是这样说的。 But what if that p is pointing at a Child ?但是如果那个p指向一个Child呢? The deduced type of o is still Parent , so at best I get a sliced object. o的推导类型仍然是Parent ,所以我最多得到一个切片对象。 No polymorphic behavior, so the whole exercise is pointless.没有多态行为,所以整个练习毫无意义。

At worst, and quite likely, I get undefined behavior.在最坏的情况下,很有可能,我会得到未定义的行为。

That's why co-variant return types have to be pointers or references.这就是为什么协变返回类型必须是指针或引用。

It is because the derived type would return a derived instance but the caller would be expecting a parent, this is different from when using pointers, in the pointer case the derived pointer can just slide into the space reserved for the parent pointer but the same is not true when talking about actual instances.这是因为派生类型会返回一个派生实例,但调用者会期待一个父对象,这与使用指针时不同,在指针情况下,派生指针可以滑入为父指针保留的空间,但相同的是谈论实际情况时并非如此。 You also have the problem that the derived method would return a derived instance but a caller using a parent pointer would have no idea about that and thus probably only destroy the parent parts.您还有一个问题,派生方法会返回派生实例,但使用父指针的调用者对此一无所知,因此可能只会破坏父部分。

you can find this helpful你会发现很有帮助

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

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