MST

星途 面试题库

面试题:C++ 虚基类对象内存布局之中等难度

请简述在一个简单的类继承体系中,包含虚基类时,对象的内存布局大概是怎样的?以一个基类 B 作为虚基类,派生类 D1 和 D2 继承自 B,最后 D3 多重继承自 D1 和 D2 为例进行说明。
22.5万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

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