所以我明白,如果你有菱形继承问题并且你进行虚拟继承,它只会创建一个基类,但是这到底是如何表示的?
在 vtable 中是否有一个指向基类的指针,当构造派生类之一时,它会查看该指针是否已经存在,如果不存在,它会创建它并使其指向基类?
所以我明白,如果你有菱形继承问题并且你进行虚拟继承,它只会创建一个基类,但是这到底是如何表示的?
在 vtable 中是否有一个指向基类的指针,当构造派生类之一时,它会查看该指针是否已经存在,如果不存在,它会创建它并使其指向基类?
你开始正确。尽管实现细节可能会有所不同,但实际上是的,vtable(或无论如何在类元数据中)中的信息足以找到基类。
对于您的第二部分,AFAIK 在任何实现中都没有“查看指针是否已经存在”。C++ 使派生最多的类负责构建所有虚拟基。因此,对于涉及Root
、和的普通菱形继承Middle1
,生成 will实例的代码:Middle2
MostDerived
MostDerived
Root
并设置一个 vptr 指向一个 vtableMostDerived
Middle1
和Middle2
MostDerived
MostDerived
我说“a vptr”而不是“vptr”,因为在基类的构造过程中Middle1
可用Root
,但任何虚函数Middle1
还没有引用MostDerived
. 由实现来解决这个问题,您可以通过查看对象大小来自己试验有多少隐藏指针用于执行此操作以及数量是否取决于是否Middle1
具有虚函数。
请注意,为构造Middle1
will 实例而发出的常用代码:
Root
并设置一个 vptr 指向一个 vtableMiddle1
Middle1
Middle1
。当我们构造 的Middle1
基类子对象时MostDerived
,我们只想执行其中两个步骤,而不是全部三个步骤。出于这个原因,您可能会发现具有多个构造函数的类的发出代码包含多个构造函数——一个用于最派生类型为类的对象,另一个用于类型为类的基类子对象.