使用空类的虚拟继承

Virtual inheritance using empty classes

本文关键字:虚拟 继承      更新时间:2023-10-16

谁能说出以下代码在C++中输出的确切原因?我收到的代码输出包含在标题注释中。它与虚拟表和 v 指针有什么关系。

/* sizeof(Empty) 1                                                                                
 sizeof(Derived1) 1 
 sizeof(Derived2) 8 
 sizeof(Derived3) 1 
 sizeof(Derived4) 16 
 sizeof(Dummy) 1
*/
#include <iostream>
using namespace std;
class Empty
{};
class Derived1 : public Empty
{};
class Derived2 : virtual public Empty
{};
class Derived3 : public Empty
{    
char c;
};
class Derived4 : virtual public Empty
{
char c;
};
class Dummy
{
 char c;
};
int main()
{
    cout << "sizeof(Empty) " << sizeof(Empty) << endl;
    cout << "sizeof(Derived1) " << sizeof(Derived1) << endl;
    cout << "sizeof(Derived2) " << sizeof(Derived2) << endl;
    cout << "sizeof(Derived3) " << sizeof(Derived3) << endl;
    cout << "sizeof(Derived4) " << sizeof(Derived4) << endl;    
    cout << "sizeof(Dummy) " << sizeof(Dummy) << endl;
    return 0;
}

首先,即使没有成员的类也必须具有非零大小。标准坚持这一点。否则,指针算术和数组将无法工作,因为零大小类的数组将在其所有元素位于同一位置!

其他尺寸不同的事实很可能是由于对向表造成的。但这在标准中没有明确规定,因此是编译器处理事物的方式的表现。

另请注意,多态性要求在基类中至少定义一个虚拟方法。这说明sizeof(Derived1)的大小与基类相同。

大小的差异是由于编译器添加vptr

sizeof(Derived1) = 1,这是因为根据C++标准,空类总是占用1字节的内存。

sizeof(Derived2) = 8,由于它继承了虚拟基类 Derived1,所以编译器(sizeof(vptr) = 864 位机器上(添加了一个 vptr 因此sizeof(Derived2)显示 8 个字节。

sizeof(Derived3) = 1因为 1 个字节的char

sizeof(Derived4) = 16,虚拟继承的内部实现完全依赖于编译器,因此您会看到 16 字节作为大小。

sizeof(Dummy) = 1 因为它包含一个字符实体。

Empty的大小为 1,

因为每个对象的大小必须至少为 1。

出于同样的原因,Derived1的尺寸为 1。

Derived2的大小为 8,

因为编译器需要 8 个字节来进行虚拟继承(可能是一个指针(。

Derived3的大小为 1,因为编译器已应用"空基类"优化。

Derived4的大小为 16,因为虚拟继承所需的 8 个字节使对象需要 8 字节对齐。

Dummy的大小为 1,因为这是char的大小。