空类的大小和派生虚拟类

Size of a empty Class & Derived Virtual Class

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

1.为什么Derived4类的大小显示8个字节??

class Empty
{};
class Derived4 : virtual public Empty
{
    char c;
};

2.而Derived2类的大小显示为4字节??

class Empty
{};
class Derived2 : virtual public Empty
{};

请注意,sizeof(any_class)是实现定义的。

但在你的情况下实际发生了什么。好吧,它使用virtual继承,大多数实现都使用隐藏指针来实现这一功能,该功能需要sizeof(pointer)字节(指针存储在派生类本身中),加上所有成员的大小(如果有的话)加上填充,如果需要加上基类的大小(在空基类的情况下,由于空基类优化,可以将其减少为零)。

有关更详细的答案,请在此网站上搜索"C++中的填充"。你会在上面找到很多主题。

为什么Derived4类的大小显示为8个字节?

class Empty
{};
class Derived4 : virtual public Empty
{
    char c;
};

在32位机器g++下,为一个空类生成1个字节(以便表示内存中的类名)。这是一种有意的行为。

您将继承Derived4中的Empty作为virtual public,结果编译器在类Derived4中创建__vptr变量作为默认值。所以类Derived4看起来像这样,

class Derived4 {
  void* __vptr; // 4 bytes
  char c; // 4 bytes as 1 char + 3 for structure padding
};

所以上面类的大小是8字节,我希望你同意。


Derived2类的大小显示为4字节?

class Empty
{};
class Derived2 : virtual public Empty
{};

这里,相同的原理适用于空的类1字节,并继承Derived4中的Empty作为插入Derived4类中的虚拟结果__vptr变量。所以,Dervied4的大小是sizeof(void*);它只不过是32位机器中4个字节的大小。

我想在Saravanan语句中添加一个事实,即空类的大小不是0字节,但当用作基类时,由于EBCO(空基类优化),基类的"开销"被消除了。