在下面的代码中,我从返回基类CBase
的函数中按值返回派生类CDerived
。
例如,CDerived
包含一个_number
字段,我理解这是";切片的";在其转换为按值返回类型CBase
期间关闭。
然而,让我困惑的是,虚拟函数Print
不知何故被转换成了它的基类版本。在这种情况下,v-table并没有被简单地切片,而是被更改了。
在我的实际代码中,_number
不存在,也不存在任何其他数据。我希望能够仅为它的v-table返回派生类,该v-table是由基类声明的。
从这个问题中,我发现我可以";围绕"工作";通过返回一个函数指针(或者我想是手工制作自己的v-table(来解决这个特殊问题,但是为什么首先要更改v-table,有什么方法可以绕过这种更改吗。
#include <iostream>
class CBase
{
public:
virtual void Print() { std::cout << "CBase" << std::endl; }
};
class CDerived : public CBase
{
int _number;
public:
explicit CDerived(int n) : _number(n) { }
virtual void Print() override { std::cout << "CDerived" << std::endl; }
};
CBase GetBase()
{
return CDerived(42);
}
int main()
{
CBase base = GetBase();
base.Print(); // Outputs CBase
return 0;
}
C++就是这样工作的。
您不返回CDerived
对象,而是返回从临时CDerived
的CBase
子对象复制的CBase
,。