3

在这里,在这段代码中,ob1 的大小是 16,这很好(因为虚拟指针),但我不明白为什么 ob2 的大小是 24。

#include <iostream>
using namespace std;
class A {
    int x;
};
class B {
    int y, z;
};
class C : virtual public A {
    int a;
};
class D : virtual public B {
    int b;
};
int main() {
    C ob1;
    D ob2;
    cout << sizeof(ob1) << sizeof(ob2) << "\n";
}

我希望 ob2 的大小为 20,但输出为 24

4

2 回答 2

8

类型对象的一种可能布局D是:

+----------+
| y        |   The B subobject (8 bytes)
| z        |
+----------+
| vptr     |   vtable pointer (8 bytes)
|          |
+----------+
| b        |   4 bytes
+----------+
| unused   |   4 bytes (padding for alignment purposes)
+----------+

那将是sizeof(ob2)24。

对齐要求由实现定义。大多数时候,最大成员对象或子对象的大小决定了对象的对齐要求。在您的情况下,最大对象的大小,即 vtable 指针,是 8 个字节。因此,该实现在 8 位边界对齐对象,并在必要时添加填充。

于 2019-08-13T16:26:35.103 回答
2

为了实现虚拟继承,D包含一个指针作为数据成员,在 64 位系统上需要 8 个字节。此外,这 8 个字节必须与 8 个字节的内存边界对齐。后一个要求反过来又要求它D本身与 8 字节内存边界对齐。实现这一点的最简单方法是sizeof(D)通过用未使用的字节 (21-24) 填充它来制作 8 的倍数。

于 2019-08-13T16:56:29.580 回答