为什么在 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
,复制自 CBase
sub-object临时CDerived
.
在下面的代码中,我 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
,复制自 CBase
sub-object临时CDerived
.