Структура объекта в случае виртуальных функций и множественного наследования

Apache Commons Lang предоставляет хороший util метод ExceptionUtils.printRootCauseStackTrace () , который печатает вложенный stacktrace 'вверх тормашками'. Результат намного более интуитивен.

, Если Вы видите результат рядом с оригиналом из printStackTrace () метод, будет ясно, куда 'еще 113' строк пошли.

7
задан curiousguy 26 July 2015 в 14:34
поделиться

2 ответа

The memory layout and the vtable layout depend on your compiler. Using my gcc for instance, they look like this:

sizeof(int) == 4
sizeof(A) == 8
sizeof(B) == 8
sizeof(C) == 20

Note that sizeof(int) and the space needed for the vtable pointer can also vary from compiler to compiler and platform to platform. The reason why sizeof(C) == 20 and not 16 is that gcc gives it 8 bytes for the A subobject, 8 bytes for the B subobject and 4 bytes for its member int c.

Vtable for C
C::_ZTV1C: 6u entries
0     (int (*)(...))0
4     (int (*)(...))(& _ZTI1C)
8     A::funA
12    (int (*)(...))-0x00000000000000008
16    (int (*)(...))(& _ZTI1C)
20    B::funB

Class C
   size=20 align=4
   base size=20 base align=4
C (0x40bd5e00) 0
    vptr=((& C::_ZTV1C) + 8u)
  A (0x40bd6080) 0
      primary-for C (0x40bd5e00)
  B (0x40bd60c0) 8
      vptr=((& C::_ZTV1C) + 20u)

Using virtual inheritance

class C : public virtual A, public virtual B

the layout changes to

Vtable for C
C::_ZTV1C: 12u entries
0     16u
4     8u
8     (int (*)(...))0
12    (int (*)(...))(& _ZTI1C)
16    0u
20    (int (*)(...))-0x00000000000000008
24    (int (*)(...))(& _ZTI1C)
28    A::funA
32    0u
36    (int (*)(...))-0x00000000000000010
40    (int (*)(...))(& _ZTI1C)
44    B::funB

VTT for C
C::_ZTT1C: 3u entries
0     ((& C::_ZTV1C) + 16u)
4     ((& C::_ZTV1C) + 28u)
8     ((& C::_ZTV1C) + 44u)

Class C
   size=24 align=4
   base size=8 base align=4
C (0x40bd5e00) 0
    vptridx=0u vptr=((& C::_ZTV1C) + 16u)
  A (0x40bd6080) 8 virtual
      vptridx=4u vbaseoffset=-0x0000000000000000c vptr=((& C::_ZTV1C) + 28u)
  B (0x40bd60c0) 16 virtual
      vptridx=8u vbaseoffset=-0x00000000000000010 vptr=((& C::_ZTV1C) + 44u)

Using gcc, you can add -fdump-class-hierarchy to obtain this information.

13
ответ дан 6 December 2019 в 08:44
поделиться

При множественном наследовании следует ожидать одного: указатель может измениться при приведении к (обычно не первому) подклассу. То, что вам следует знать при отладке и ответах на вопросы интервью.

5
ответ дан 6 December 2019 в 08:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: