面试题答案
一键面试- 基类
B
:- 基类
B
本身的数据成员。 - 如果有虚函数,会有一个虚函数表指针(vptr)指向虚函数表。
- 基类
- 派生类
D1
和D2
:D1
和D2
首先包含各自从B
继承而来的数据成员(在多重继承下,由于B
是虚基类,D1
和D2
不会各自重复存储B
的数据成员,而是共享一份)。D1
和D2
各自的数据成员。- 如果
D1
或D2
有新的虚函数,会有自己的虚函数表指针(vptr)指向新的虚函数表。同时,虚函数表中会包含从B
继承来的虚函数(如果有覆盖则为覆盖后的版本)。 - 对于虚基类
B
,D1
和D2
会各自包含一个指向虚基类B
子对象偏移位置的指针(虚基表指针,vbptr),通过这个指针可以在运行时找到共享的B
子对象。
- 派生类
D3
:D3
包含从D1
继承来的数据成员(不重复包含B
的数据成员,通过D1
的虚基表指针找到共享的B
子对象)。D3
包含从D2
继承来的数据成员(同样不重复包含B
的数据成员,通过D2
的虚基表指针找到共享的B
子对象)。D3
自身的数据成员。- 如果
D3
有新的虚函数,会有自己的虚函数表指针(vptr)指向新的虚函数表。虚函数表中会包含从D1
、D2
继承来的虚函数(如果有覆盖则为覆盖后的版本)。 - 整体上,
D3
的内存布局是D1
部分在前,D2
部分在后(顺序取决于编译器实现),中间共享一份虚基类B
的子对象。通过D1
和D2
中的虚基表指针可以正确定位到共享的B
子对象。