多继承
Example:¶
C++
class A {
public:
int j;
virtual void fooA();
};
class B {
public:
double k;
virtual void fooB();
};
class C: public A, public B {
int l;
virtual void fooC();
};
int main() {
C c;
}
gcc¶
Bash
Vtable for A
A::_ZTV1A: 3u entries
0 (int (*)(...))0
8 (int (*)(...))(& _ZTI1A)
16 (int (*)(...))A::fooA
Class A
size=16 align=8
base size=12 base align=8
A (0x0x3fff822a04e0) 0
vptr=((& A::_ZTV1A) + 16u)
Vtable for B
B::_ZTV1B: 3u entries
0 (int (*)(...))0
8 (int (*)(...))(& _ZTI1B)
16 (int (*)(...))B::fooB
Class B
size=16 align=8
base size=16 base align=8
B (0x0x3fff822a0540) 0
vptr=((& B::_ZTV1B) + 16u)
Vtable for C
C::_ZTV1C: 7u entries
0 (int (*)(...))0
8 (int (*)(...))(& _ZTI1C)
16 (int (*)(...))A::fooA
24 (int (*)(...))C::fooC
32 (int (*)(...))-16
40 (int (*)(...))(& _ZTI1C)
48 (int (*)(...))B::fooB
Class C
size=40 align=8
base size=36 base align=8
C (0x0x3fff8ae30e70) 0
vptr=((& C::_ZTV1C) + 16u)
A (0x0x3fff822a05a0) 0
primary-for C (0x0x3fff8ae30e70)
B (0x0x3fff822a0600) 16
vptr=((& C::_ZTV1C) + 48u)
很明显类C有两个虚指令,vptrA和vptrB,但只有一个虚表,两个指针指向同一虚表中的不同偏移位置。
clang¶
Bash
clang++ -Xclang -fdump-record-layouts test.cpp -c
*** Dumping AST Record Layout
0 | class A
0 | (A vtable pointer)
8 | int j
| [sizeof=16, dsize=12, align=8,
| nvsize=12, nvalign=8]
*** Dumping AST Record Layout
0 | class B
0 | (B vtable pointer)
8 | double k
| [sizeof=16, dsize=16, align=8,
| nvsize=16, nvalign=8]
*** Dumping AST Record Layout
0 | class C
0 | class A (primary base)
0 | (A vtable pointer)
8 | int j
16 | class B (base)
16 | (B vtable pointer)
24 | double k
32 | int l
| [sizeof=40, dsize=36, align=8,
| nvsize=36, nvalign=8]
很明显类C有两个虚指令,vptrA和vptrB,但只有一个虚表,两个指针指向同一虚表中的不同偏移位置。
Bash
clang++ -Xclang -fdump-vtable-layouts test.cpp -c
Vtable for 'C' (7 entries).
0 | offset_to_top (0)
1 | C RTTI
-- (A, 0) vtable address --
-- (C, 0 ) vtable address --
2 | void A::fooA()
3 | void C::fooC()
4 | offset_to_top (-16)
5 | C RTTI
-- (B, 16) vtable address --
6 | void B::fooB()
VTable indices for 'C' (1 entries).
1 | void C::fooC()
Vtable for 'A' (3 entries).
0 | offset_to_top (0)
1 | A RTTI
-- (A, 0) vtable address --
2 | void A::fooA()
VTable indices for 'A' (1 entries).
0 | void A::fooA()
Vtable for 'B' (3 entries).
0 | offset_to_top (0)
1 | B RTTI
-- (B, 0) vtable address --
2 | void B::fooB()
VTable indices for 'B' (1 entries).
0 | void B::fooB()