虚拟基类是如何存储的

How is virtual base classes stored?

本文关键字:存储 何存储 基类 虚拟      更新时间:2023-10-16

所以我理解,如果你有钻石继承问题,你做虚拟继承它只创建一个基类然而,这究竟是如何表示的?

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

你从右边开始。尽管实现细节可能有所不同,但实际上虚函数表中(或者无论如何在类元数据中)有足够的信息来查找基类。

对于你的第二部分,我想在任何实现中都没有"查看指针是否已经存在"。c++使派生最多的类负责构造所有虚基。因此,对于涉及Root, Middle1, Middle2MostDerived的正常菱形继承,用于构造MostDerived实例的代码将:

  • 构造Root并设置vptr指向MostDerived的虚函数表
  • 构建Middle1Middle2
  • 构建MostDerived
  • 的数据成员
  • 执行MostDerived的构造函数体

我说"一个vptr"而不是"vptr",因为在Middle1的构造过程中,Root基类是可用的,但Middle1的任何虚函数还没有引用MostDerived中定义的覆盖。这取决于实现来解决这个问题,你可以自己实验一下,看看对象大小,有多少隐藏指针被用来做这件事,以及这个数字是否取决于Middle1是否有虚函数。

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

  • 构造Root并设置vptr指向Middle1的虚函数表
  • 构建Middle1
  • 的数据成员
  • 执行Middle1的构造函数体

当我们构造MostDerivedMiddle1基类子对象时,我们只想执行其中两个步骤,而不是全部三个步骤。由于这个原因,您可能会发现具有多个构造函数的类所发出的代码包含多个构造函数——一个用于派生类型为类的对象,另一个用于派生类型为类的基类子对象。