C++虚继承初始化顺序

标签 c++ virtual multiple-inheritance

你好, 如您所见,示例中的构建顺序是:– U1 U2 Y X V2 V1 V3 V4 B1 B2 D

我理解:U1 U2 Y X 被初始化,因为 V2 是对 D 的第一个直接虚拟继承,为了初始化它,需要初始化这些首先 U1 U2 Y X 。在那之后V2 被初始化了,但是为什么V1V3 之前被初始化,尽管从V3 有直接的虚拟继承。

请忽略节点和箭头的数字,注意红色箭头为非虚拟继承,黑色箭头为虚拟。

注意:原始文件可以找到there .

最佳答案

这是我对这个例子的理解。它符合施工顺序,所以我相信它是正确的。但是,我不确定。

首先,箭头的数字很重要,因为它们告诉您定义基类的顺序。以D为例,类定义如下:

class D : virtual V2, B1, B2, virtual v3 {...}

鉴于此,我的下一步是遍历图并将所有类放入深度优先顺序,无论它们是否为虚拟。大括号表示基类。括号表示已经在我的类列表中的虚拟基类:

D {V2 {X {U1, U2}, Y {(U2), (U1)}}, B1 {V1, (V2), V3 {(Y), (U2)}, V4}, B2 {(V4-V1)}, (V3)

对我来说,这是

  • 要构造 D,首先我需要 V2。
  • V2 需要 X,X 需要 U1 和 U2。
  • 下一个 V2 需要 Y,Y 需要 U2 和 U1,但两者都已经在我的列表中。
  • 下一个 D 需要 B1。
  • B1 需要 V1、V2、V3 和 V4,V2 已经在我的列表中。
  • V3 需要 Y 和 U2,但两者都已在我的列表中。
  • 下一个 D 需要 B2,它需要 V4 到 V1,所有这些都在我的列表中。
  • 最后,D 需要 V3,但同样,它已经在我的列表中。

鉴于此,我现在将删除多余的基类,留下:

D {V2 {X {U1, U2}, Y}, B1 {V1, V3, V4}, B2}

下一部分是找到非虚拟基类并对我的列表进行调整。

  • V2 需要 X 和 Y,其中 Y 是虚拟的,因此 Y 必须在 X 之前。

关于此的额外要点:鉴于您的问题,我希望您也认为 U2 应该在 U1 之前,因为 Y 在 X 之前构造,并且在 Y 中,U2 首先导出。但是,这不会发生。相反,X 的虚拟基类是按顺序完成的,然后是 Y,最后是 X。

这会将我的列表调整为以下内容:

D {V2 { {U1, U2}, Y, X}, B1 {V1, V3, V4}, B2}

最后,B1是非虚拟的,所以需要在V1、V3、V4之后。这留下了:

D {V2 { {U1, U2}, Y, X}, {V1, V3, V4}, B1, B2}

请注意,B2 也是非虚拟的,如果它不在我的列表中,则需要考虑。

这给了我一个令我满意的订单。唯一的问题是我将派生类列在基类之前,我们知道基类是先构造的。这是一个问题的唯一两个地方是

  • D,需要放在最后。
  • V2,需要在其子项之后。

所以我将调整我的列表以将这两项移动,V2 移到 X 之后,D 移到 B2 之后。

{ { {U1, U2}, Y, X} V2, {V1, V3, V4}, B1, B2} D

现在我将删除括号并:

U1, U2, Y, X, V2, V1, V3, V4, B1, B2, D

您可以看到这与图表中构造函数的顺序相匹配,并且实际上与我使用 Visual Studio 2012 构建时调用的顺序相匹配。

关于C++虚继承初始化顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15885601/

相关文章:

c++ - 在 OpenCV 中设置像素值(奇怪的结果)

c++ - 使用单例时内存泄漏

c++ - 这个简单的代码会导致内存泄漏吗?

c++ - C++ 中的 "As a rule of thumb, make all your methods virtual"- 合理的建议?

c++ - 多重继承导致的“无法访问的直接基础”

abstract-class - 多重继承解决方法

c++ - 为什么当我们将 lambda 发送到 std::function 时,自动模板类型推导不起作用?

C++ 继承——为什么我的函数没有被使用?

c++ - 调用具有多重继承的添加类的成员

c++ - 使用 QIconEngine 和透明度自定义 QIcon