【问题标题】:Size of a empty Class & Derived Virtual Class空类和派生虚拟类的大小
【发布时间】:2013-08-10 17:46:35
【问题描述】:

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

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

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

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

【问题讨论】:

  • 填充到单词边界?如果添加 char 字段会怎样?
  • 这是实现定义的,因此几乎不可能回答,但你为什么要关心呢?
  • 我敢打赌。 vtable 导致了额外的 4 个字节,并且感觉“char”只有 1 个字节,最终总共有 5 个字节。编译器可能在使用 8 个字节值的指令上将其设置为 8 个字节
  • 你会注意到Derived4的布局中有一个int32_t(**)(...)类型的隐藏指针:coliru.stacked-crooked.com/…
  • 正如其他人所说,这是实现定义的。该标准仅讨论各种类型的最小大小(例如,char 最小为 1 个字节,但原则上它可以是任何更大的数字)。顺便说一句,您使用的是什么编译器?

标签: c++ class oop sizeof


【解决方案1】:

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

但是在您的情况下实际发生了什么。嗯,它使用virtual 继承,大多数实现使用隐藏指针来实现这个特性,它花费sizeof(pointer) 字节(指针存储在派生类本身中),加上所有成员的大小(如果有)填充如果需要基类的大小(可以减少为零,如果基类为空,由于空基优化)。

如需更详细的答案,请在本站搜索"padding in C++"。你会发现很多关于它的主题。

【讨论】:

  • 即使在虚拟继承的情况下,Vptr 和 Vtable 是否出现在图片中,我认为它出现在图片中只有当 yiu 在你的类中具有虚拟功能时才需要 Vtable..,请澄清
  • @GeekPanther:是的。一个vptr 用于一个虚拟基地。因此,如果您有两个虚拟基类,则将有两个vptr,并且将相应地计算类的大小。如果基类为空,编译器可能会对此进行优化,因此它可能只有一个,而不是两个。
  • 那么在这种情况下,Vtable 的内容是什么,如在 Vfunction 的情况下它包含 Vfunctions 的地址,如果是虚拟继承(没有任何 VFunc),Vtable 的内容是什么? ?
  • @GeekPanther:我想它应该是空的,但我不确定,因为编译器在每个新版本中都会做很多技巧,在编译器实现方面没有什么是永久的。 你的程序不能依赖那些血淋淋的细节
【解决方案2】:

为什么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 作为虚拟结果 __vptr 变量插入到 Derived4 类中。所以,Dervied4 的大小是sizeof(void*);这在 32 位机器中不过是 4 个字节的大小。

【讨论】:

    【解决方案3】:

    我会在 Saravanan 声明中补充说,空类的大小是非 0 字节,但是当用作基类时,由于 EBCO(空基类优化),基类的“开销”被删除了。

    【讨论】:

      猜你喜欢
      • 2021-04-14
      • 2013-02-26
      • 2020-09-30
      • 2020-02-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-04
      • 1970-01-01
      相关资源
      最近更新 更多