为什么在 C++ 中按值*返回虚拟 class 会改变 v-table?

Why does returning a virtual class *by value* in C++ alter the v-table?

在下面的代码中,我 return 从函数 return 派生 class CDerived by-value基地 class, CBase.

例如,CDerived 包含一个 _number 字段,据我所知,这是在转换为按值 return 类型的过程中被“切掉”的,CBase.

然而,这里让我感到困惑的是虚函数 Print 不知何故被转化为它的基础-class 版本。在这种情况下,v-table 并没有简单地被切片,而是被改变了。

在我的实际代码中 _number 不存在,也不存在任何其他数据。我希望能够 return 派生 class 仅因为它是 v-table,它由基声明。

this question 我看到我可以通过 returning 一个函数指针(或者我想制作我自己的 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++ 的工作原理。

你没有return一个CDerived对象,你return一个CBase复制自 CBasesub-object临时CDerived.