所以我理解,如果你有钻石继承问题并且你进行虚拟继承,它只会创建一个基类,但是这究竟是如何表示的?
在vtable中有一个指向基类的指针,当构造其中一个派生类时,它会查看该指针是否已存在,如果不存在则创建它并使其指向基类?
答案 0 :(得分:1)
你从右开始。虽然实现细节可能会有所不同,但实际上是,vtable中的信息(或类数据库中的任何信息)足以找到基类。
对于你的第二部分,AFAIK在任何实现中都没有“看看指针是否已存在”。 C ++使得派生最多的类负责构建所有虚拟基础。因此,通过涉及Root
,Middle1
,Middle2
和MostDerived
的普通钻石继承,用于构造MostDerived
实例的代码将:
Root
并将vptr设置为指向MostDerived
Middle1
和Middle2
MostDerived
MostDerived
我说“vptr”而不是“vptr”,因为在构造Middle1
期间Root
基类可用但Middle1
的任何虚函数都没有't 仍然引用MostDerived
中定义的覆盖。由实现来解决这个问题,您可以通过查看对象大小来自己进行实验,使用多少隐藏指针来执行此操作以及数字是否取决于Middle1
是否具有虚函数。
请注意,用于构造Middle1
实例的通常代码将:
Root
并将vptr设置为指向Middle1
Middle1
Middle1
。当我们构建Middle1
MostDerived
基类子对象时,我们只想做其中两个步骤,而不是全部三个步骤。因此,您可能会发现具有多个构造函数的类的发出代码包含多个构造函数 - 一个用于最大派生类型为类的对象,另一个用于类型为类的基类子对象。