Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/151.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;:无指针的协变返回类型_C++_Pointers_Covariant Return Types - Fatal编程技术网

C++ C++;:无指针的协变返回类型

C++ C++;:无指针的协变返回类型,c++,pointers,covariant-return-types,C++,Pointers,Covariant Return Types,我通过继承创建了两个简单的类,并在子类中添加了一个虚函数和重写 类父类 { 公众: 虚拟父foo(); }; 类子:公共父类 { 公众: 子foo()覆盖; }; 在这种情况下,我的重写函数得到一个错误:error C2555:'Child::foo':重写虚拟函数的返回类型与'Parent::foo'不同且不协变。 如果我使用指针更改返回类型: 类父类 { 公众: 虚拟父*foo(); }; 类子:公共父类 { 公众: 子*foo()覆盖; }; 错误消失了! 我不明白为什么返回类型的协方

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

类父类
{
公众:
虚拟父foo();
};
类子:公共父类
{
公众:
子foo()覆盖;
};
在这种情况下,我的重写函数得到一个错误:
error C2555:'Child::foo':重写虚拟函数的返回类型与'Parent::foo'不同且不协变。

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

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

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

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


您可以找到有用的

协变返回类型的概念是polymorpihc返回类型。在C++中,没有指针或引用就不能有运行时多态性。让我们暂时忽略大部分困难,假装这是可能的。下面是我的代码,它通过您的
父接口处理事情:

void bar(Parent * p) {
  auto o = p->foo();
}
什么是
o
?当然是家长了。在
Parent::foo
的返回类型中这样说。但是如果那
p
指向一个
呢?导出的
o
类型仍然是
Parent
,因此我最多只能得到一个切片对象。没有多态性行为,因此整个练习毫无意义

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


这就是共变量返回类型必须是指针或引用的原因。

Minor旁白:它不必涉及指针——您也可以使用引用。“函数不使用指针,我必须返回每个函数的基类并将返回的类型转换为子类型”否,您不能将父对象转换为子对象。返回的对象是完整对象,没有子对象。如果您说
返回子对象您想返回的<代码>子< /Cl>对象被剪切,只有一个拷贝>代码>父< /COD>部分返回。考虑基类是抽象的情况(因为它通常应该用于接口类):您甚至不能返回它的对象,是吗?