每个非虚拟对象包含在基类中定义的数据成员的一个副本。这种重复浪费了空间,并要求您在每次访问基类成员时都必须指定所需的基类成员的副本。
当将某个基类指定为虚拟基时,该基类可以多次作为间接基而无需复制其数据成员。基类的数据成员的单个副本由将其用作虚拟基的所有基类共享。
当声明虚拟基类时,virtual 关键字将显示在派生类的基列表中。
请考虑下图中的类层次结构,它演示了模拟的午餐排队。
模拟午餐排队图
在该图中,Queue 是 CashierQueue 和 LunchQueue 的基类。但是,当将这两个类组合成 LunchCashierQueue 时,会出现以下问题:新类包含类型 Queue 的两个子对象,一个来自 CashierQueue,另一个来自 LunchQueue。下图显示了概念上的内存布局(实际物理内存布局可能会进行优化)。
模拟午餐排队对象
请注意,Queue 对象中有两个 LunchCashierQueue 子对象。以下代码将 Queue 声明为虚拟基类:
// deriv_VirtualBaseClasses.cpp
// compile with: /LD
class Queue {};
class CashierQueue : virtual public Queue {};
class LunchQueue : virtual public Queue {};
class LunchCashierQueue : public LunchQueue, public CashierQueue {};
virtual 关键字可确保只包含子对象 Queue 的一个副本(请参阅下图)。
使用虚拟基类模拟午餐排队对象
一个类可以同时具有一个给定类型的虚拟组件和非虚拟组件。下图演示了这种情况。













