如何存储虚拟基类?

时间:2013-06-07 20:51:49

标签: c++ inheritance multiple-inheritance

所以我理解,如果你有钻石继承问题并且你进行虚拟继承,它只会创建一个基类,但是这究竟是如何表示的?

在vtable中有一个指向基类的指针,当构造其中一个派生类时,它会查看该指针是否已存在,如果不存在则创建它并使其指向基类?

1 个答案:

答案 0 :(得分:1)

你从右开始。虽然实现细节可能会有所不同,但实际上是,vtable中的信息(或类数据库中的任何信息)足以找到基类。

对于你的第二部分,AFAIK在任何实现中都没有“看看指针是否已存在”。 C ++使得派生最多的类负责构建所有虚拟基础。因此,通过涉及RootMiddle1Middle2MostDerived的普通钻石继承,用于构造MostDerived实例的代码将:

  • 构建Root并将vptr设置为指向MostDerived
  • 的vtable
  • 构建Middle1Middle2
  • 构建MostDerived
  • 的数据成员
  • 执行MostDerived
  • 的构造函数的主体

我说“vptr”而不是“vptr”,因为在构造Middle1期间Root基类可用但Middle1 的任何虚函数都没有't 仍然引用MostDerived中定义的覆盖。由实现来解决这个问题,您可以通过查看对象大小来自己进行实验,使用多少隐藏指针来执行此操作以及数字是否取决于Middle1是否具有虚函数。

请注意,用于构造Middle1实例的通常代码将:

  • 构建Root并将vptr设置为指向Middle1
  • 的vtable
  • 构建Middle1
  • 的数据成员
  • 执行Middle1
  • 的构造函数的主体

当我们构建Middle1 MostDerived基类子对象时,我们只想做其中两个步骤,而不是全部三个步骤。因此,您可能会发现具有多个构造函数的类的发出代码包含多个构造函数 - 一个用于最大派生类型为类的对象,另一个用于类型为类的基类子对象。