菱形(多重)虚拟继承中的 C++ 成员和 vtable 顺序

C++ Member and vtable order in diamond (multiple) virtual inheritance

我想知道 C++ 中成员变量和 vtable 指针在菱形虚拟继承中的顺序。

考虑以下继承:

class Base
{
    int b;
};

class Derived: public virtual Base
{
    int d;
};

class Derived2: public virtual Base
{
    int d2;
};

class Derived3: public Derived, public Derived2
{
    int d3;
};

我想知道 class Derived3 的内存布局。 我在线查看了以下链接:

c++ data alignment /member order & inheritance

C++ Inheritance Memory Model

通过上面的链接后,我觉得 Derived3 的内存布局可能是:

void* vtable_ptr1 //vtable pointer of Derived
int d //Derived
void* vtable_ptr2 //vtable pointer of Derived2
int d2 //Derived2
int b //Base? not sure where will this be.
int d3 //Derived3

网上编译器给出Derived3的大小为40字节,所以我觉得(假设指针8字节,int 4字节)int b 必须在 vtable_ptr2 (8( vtable_ptr1) + 4(d) + [4 填充] + 8(vtable_ptr2) + 4(d2) + 4(b) + 4(d3) + [4 class padding]) 或 vtable_ptr1 (4(b) + [ 4 填充] + 8(vtable_ptr1) + 4(d) + [4 填充] + 8( vtable_ptr2) + 4(d2) + 4(d3)) 这样填充就会出现并增加class 的大小为 40.

总而言之,我有以下问题:

顺序正确吗?如果不是,成员变量和 vtable 指针的正确顺序是什么?

what is the correct ordering of member variables and vtable pointers?

没有“正确的顺序”。这在 C++ 标准中没有指定。每个编译器都可以按照符合 C++ 标准的任何方式自由安排此 class 层次结构的内存布局。

在这种情况下,编译器可能会根据一些固定的规则集来选择 class 的布局。或者,编译器可能会尝试在多种可能性之间进行优化,并选择一种可以利用与硬件相关的因素(例如对象的首选对齐方式)的布局,以尽量减少任何所需的填充。这完全取决于编译器。

此外:如果您查看 C++ 标准的文本,您将找不到任何提及“vtable”的内容。它不在那里。这只是虚class方法和虚继承最常见的实现机制。它完全符合 C++ 标准,而不是指针,C++ 编译器将两字节索引用于 table,而不是整个指针——进入包含记录的 table定义每个特定的 class 的虚拟属性。只要具有虚拟属性的所有 class 的数量不超过 65536,这就可以很好地工作。

换句话说:您无法保证此 class 在内存中的布局或大小。它未在 C++ 标准中指定,完全由实现定义。