c++ - 虚基类是如何存储的?

标签 c++ inheritance multiple-inheritance

所以我明白,如果您有菱形继承问题并且您进行虚拟继承,它只会创建一个基类,但是这究竟是如何表示的?

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

最佳答案

你的起点是对的。尽管实现细节可能会有所不同,但实际上是的,vtable 中的信息(或无论如何在类元数据中)足以找到基类。

对于您的第二部分,AFAIK 在任何实现中都没有“查看指针是否已经存在”。 C++ 使派生最多的类负责构造所有虚拟基类。因此,对于涉及 RootMiddle1Middle2MostDerived 的普通菱形继承,发出的代码构造MostDerived 将:

  • 构造Root并设置一个vptr指向MostDerived的vtable>
  • 构造Middle1Middle2
  • 构造MostDerived的数据成员
  • 执行MostDerived的构造函数主体

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

请注意,为构造 Middle1 实例发出的常用代码将:

  • 构造Root并设置一个vptr指向Middle1的vtable>
  • 构造Middle1的数据成员
  • 执行 Middle1 的构造函数主体。

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

关于c++ - 虚基类是如何存储的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16992747/

相关文章:

c++ - 取消引用 boost::ptr_vector

c++ - 在 C++11 中使用 SFINAE 在具有相同签名的两个函数之间进行选择

c++ - 在堆上存储 unique_ptr 的最简单方法是什么?

python - 有没有一种好方法让一个类继承两个类之一

c++ - 静态分配的内存在静态取消初始化期间会变得无效吗?

C++ 继承问题

java - 分层继承

c# - 为什么在类中实现的 C# 接口(interface)方法必须是公共(public)的?

c++ - 允许其他基类实现虚函数

C++接口(interface)多重继承,方法相同