ss A: public virtual X {public: int i;}; class B: public virtual X {public: int j;}; class C: public virtual A, public virtual B {public: int k;}; int main() { C c; A a; B b; cout <<"first level derived A:"<< a.x << endl; cout <<"first level derived B:"<< b.x << endl; cout <<"second level derived C:"<< c.x << endl; cout <<"second level derived C->A:"<< c.A::x << endl; cout <<"second level derived C->B:"<< c.B::x << endl; return 0; }
输出结果:不同 derived class object 中virtual base class 不是共享的,而同一继承层次中的 virtual base class 是共享的。对象a、b、c 都需要存储各自virtual base class 的地址。因此编译器会在每个对象中产生指向 virtual base class 地址的指针,指向 virtual base class X,对 virtual base class 读取操作在执行期间才能确定的。
(gdb) r
Starting program: /ObjectModel/chap02/test
Breakpoint 1, main () at test.cpp:18
18 C c;
(gdb) s
C::C (this=0xbffff024, __in_chrg=
, __vtt_parm=
) at test.cpp:14 14 class C: public virtual A, public virtual B {public: int k;}; (gdb) s X::X (this=0xbffff034) at test.cpp:5 5 class X { (gdb) s A::A (this=0xbffff02c, __vtt_parm=0x8048c1c
, __in_chrg=
) at test.cpp:10 10 class A: public virtual X {public: int i;}; (gdb) s B::B (this=0xbffff038, __vtt_parm=0x8048c20
, __in_chrg=
) at test.cpp:12 12 class B: public virtual X {public: int j;}; (gdb) s main () at test.cpp:19 19 A a; (gdb) s A::A (this=0xbffff00c, __in_chrg=
, __vtt_parm=
) at test.cpp:10 10 class A: public virtual X {public: int i;}; (gdb) s X::X (this=0xbffff014) at test.cpp:5 5 class X { (gdb) s main () at test.cpp:20 20 B b; (gdb) s B::B (this=0xbffff018, __in_chrg=
, __vtt_parm=
) at test.cpp:12 12 class B: public virtual X {public: int j;}; (gdb) s X::X (this=0xbffff020) at test.cpp:5 5 class X { (gdb) s main () at test.cpp:22 22 cout <<"first level derived A:"<< a.x << endl; (gdb) n first level derived A:-1210826250 23 cout <<"first level derived B:"<< b.x << endl; (gdb) n first level derived B:1 24 cout <<"second level derived C:"<< c.x << endl; (gdb) n second level derived C:0 25 cout <<"second level derived C->A:"<< c.A::x << endl; (gdb) n second level derived C->A:0 26 cout <<"second level derived C->B:"<< c.B::x << endl; (gdb) n second level derived C->B:0 28 return 0;
总结:
当 class 中没有显式声明 default constructor,若是上述四种情况之一,编译器会根据需要合成 nontrivial default constructor。但是编译器不会初始化 class 中 nonstatic data member,只会初始化 base class subobjects 和 member class objects;