为什么在C++中按值*返回虚拟类会改变v表



在下面的代码中,我从返回基类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对象,而是返回从临时CDerivedCBase子对象复制的CBase

相关内容

  • 没有找到相关文章

最新更新