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