当前位置:  开发笔记 > 编程语言 > 正文

为什么具有虚函数的类与没有的类对齐?

如何解决《为什么具有虚函数的类与没有的类对齐?》经验,为你挑选了1个好方法。

受理查德鲍威尔的这次cppcon谈话的启发,我创建了以下代码片段来愚弄:

#include 
using std::cout;
using std::endl;

struct erdos
{
  void who()
  {
    cout << "erdos" << endl;
  }
  float f1;
  float f2;
};

struct fermat : public erdos
{
  float f3;
};

struct fermat2 : public fermat
{
  float f4;
};

struct fermat3 : public fermat2
{
  float f5;
};

int main(void)
{
  erdos e;
  cout << "sizeof(e)" << sizeof(e) << endl;
  fermat f;
  cout << "sizeof(f)" << sizeof(f) << endl;
  fermat2 f2;
  cout << "sizeof(f2)" << sizeof(f2) << endl;
  fermat3 f3;
  cout << "sizeof(f3)" << sizeof(f3) << endl;
  cout << "sizeof(void*)" << sizeof(void*) << endl;
  cout << "sizeof(float)" << sizeof(float) << endl;
  return 0;
}

哪个会打印:

sizeof(e)8
sizeof(f)12
sizeof(f2)16
sizeof(f3)20
sizeof(void*)8
sizeof(float)4

添加virtualwho()我之后得到这个

sizeof(e)16
sizeof(f)24
sizeof(f2)24
sizeof(f3)32
sizeof(void*)8
sizeof(float)4

现在,添加结构的大小void*很简单,但为什么在虚拟情况下会出现这种填充(理查德在他的演讲中也提到过)而不是非虚拟情况?

sizeof(e)16 - 8 = 8 
sizeof(f)24 - 8 = 16 but is in fact 12 (padding 4)
sizeof(f2)24 - 8 = 16 matches
sizeof(f3)32 - 8 = 24 but is in fact 20 (padding 4)

我在Ubuntu 14.04 64位上使用gcc 5.3.0和clang 3.7.1进行了测试



1> Nicol Bolas..:
sizeof(void*)8

嗯,这是你的答案.

假设您的实现只需要一个指针来处理虚拟查找,那就是对齐的原因.64位编译时,指针需要64位空间(这就是我们称之为"64位"的原因).但它也需要64位对齐.

因此,在64位编译中存储指针的任何数据结构也必须是64位对齐的.对象的对齐必须是8字节对齐,并且大小必须填充到8个字节(出于数组索引的原因).如果你让其中一个float成员成为指针,你会看到同样的事情.


@Patryk:非虚拟`f3`包含5个大小为4的成员.5×4 = 20.`float`可能是4字节对齐的.因为20可被4整除,所以没有填充物.虚拟`f3包含5个大小为4的成员和另一个大小为8的成员.5×4 + 8 = 28.`float`可能是4字节对齐的,指针可能是8字节对齐的.由于使用了更高的对准要求,结构具有8字节的对齐.由于20不能被8均匀整除,编译器需要将填充添加到最接近的8的倍数,即32.当然这只是推测.编译器可能只决定添加2个6字节字段而没有对齐要求.
推荐阅读
农大军乐团_697
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有