虚拟继承表如何在g ++中工作?

时间:2012-03-30 17:36:21

标签: c++ g++ internals vtable virtual-inheritance

我正在努力更好地理解虚拟继承在实践中是如何工作的(也就是说,不是根据标准,而是在像g++这样的实际实现中)。实际问题在底部,以粗体显示。

所以,我自己构建了一个继承图,其中包括这些简单的类型:

struct A {
  unsigned a;
  unsigned long long u;
  A() : a(0xAAAAAAAA), u(0x1111111111111111ull) {}
  virtual ~A() {}
};

struct B : virtual A {
  unsigned b;
  B() : b(0xBBBBBBBB) {
    a = 0xABABABAB;
  }
};

(在整个层次结构中,我还有C: virtual ABC: B,C,因此虚拟继承是有意义的。)

我编写了几个函数来转储实例的布局,获取vtable指针并打印前6个8字节值(任意适合屏幕),然后转储对象的实际内存。这看起来像这样:

转储A对象:

actual A object of size 24 at location 0x936010
vtable expected at 0x402310 {
          401036,          401068,          434232,               0,               0,               0,
}
1023400000000000aaaaaaaa000000001111111111111111
[--vtable ptr--]

转储B对象和A对象所在的位置,通过在相应位置打印很多A来表示。

actual B object of size 40 at location 0x936030
vtable expected at 0x4022b8 {
          4012d2,          40133c,        fffffff0,        fffffff0,          4023c0,          4012c8,
}
b822400000000000bbbbbbbb00000000e022400000000000abababab000000001111111111111111
                                AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA  (offset: 16)

如您所见,A的{​​{1}}部分位于B字节到16对象开头的偏移处(如果我已经实例化B并将其dyn转换为BC )。

我原本期望B*(或至少一个16,由于对齐)显示在表格的某个地方,因为程序必须查找2在运行时的实际位置(偏移量)。 那么,布局真的如何?


编辑:转储是通过致电Adump

完成的
dumpPositions

1 个答案:

答案 0 :(得分:1)

答案实际上是在Itanium ABI中记录的。特别是第2.5节包含虚拟表的布局。