C++ : Covariant return type without pointer

拥有回忆 提交于 2020-11-28 15:12:41

问题


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'

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 ?


回答1:


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. 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:

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

What is o? Well, it's Parent of course. Says so in Parent::foo's return type. But what if that p is pointing at a Child? The deduced type of o is still Parent, so at best I get a sliced object. 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.




回答2:


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



来源:https://stackoverflow.com/questions/48001688/c-covariant-return-type-without-pointer

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!