首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >c++虚拟继承初始化顺序

c++虚拟继承初始化顺序
EN

Stack Overflow用户
提问于 2013-04-08 17:49:14
回答 2查看 517关注 0票数 3

嗨,如您所见,示例中的构造顺序是:- U1 U2 Y X V2 V1 V3 V4 B1 B2 D

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

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

注:原始文件可找到http://webcourse.cs.technion.ac.il/236703/Winter2012-2013/ho/WCFiles/12%2520-%2520Multiple%2520Inheritance%2520-%2520c%2B%2B11.pdf

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-04-08 19:18:31

这是我对这个例子的理解。它符合建筑订单,所以我相信它是正确的。不过,我不确定。

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

代码语言:javascript
复制
class D : virtual V2, B1, B2, virtual v3 {...}

在这种情况下,我的下一步是遍历图,并将所有类置于深度一阶,而不管它们是否是虚拟的。大括号表示基类。括号表示已经在我的类列表中的虚拟基类:

代码语言:javascript
复制
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,它需要U2和U1,但两者都在我的列表中。
  • 下一个D需要B1。
  • B1需要V1、V2、V3和V4,V2已经在我的列表中了。
  • V3需要Y和U2,但两者都在我的列表中。
  • 接下来的D需要B2,它需要V4通过V1,所有这些都在我的列表中。
  • 最后,D需要V3,但是,它已经在我的列表中了。

既然如此,我现在将删除冗余基类,如下所示:

代码语言:javascript
复制
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。

这将调整我的列表如下:

代码语言:javascript
复制
D {V2 { {U1, U2}, Y, X}, B1 {V1, V3, V4}, B2}

最后,B1是非虚拟的,因此它需要在V1、V3和V4之后出现.这意味着:

代码语言:javascript
复制
D {V2 { {U1, U2}, Y, X}, {V1, V3, V4}, B1, B2}

请注意,B2也是非虚拟的,如果它不是我列表中的最后一个,就需要考虑它。

这给了我一个令我满意的命令。唯一的问题是,我在基类之前列出了派生类,而且我们知道基类是先构造的。剩下的两个地方都是问题所在

  • D,这必须是最后一个。
  • V2,它需要的是它的孩子。

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

代码语言:javascript
复制
{ { {U1, U2}, Y, X} V2, {V1, V3, V4}, B1, B2} D

现在,我将删除括号,并:

代码语言:javascript
复制
U1, U2, Y, X, V2, V1, V3, V4, B1, B2, D

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

票数 3
EN

Stack Overflow用户

发布于 2013-04-08 18:57:27

我只想回答你关于V1和V3顺序的问题。

第一步是:

深度优先中应用拓扑排序排序继承数据,左-右扫描,

  • 虚拟继承和非虚拟继承是一样对待的

根据这个规则,V1在V3之前出现: V1更深,并且位于V3的左侧,而不管继承类型如何。从D到相关节点的连续祖先的直接继承等级定义了从左到右的顺序。该秩由图的节点之间的边所携带(因此不能忽略):V3具有秩(3),而V2有秩(1) -而且(2,2)被较高的节点取消-而V1具有秩(2,1)。因此,这三个节点之间的顺序是V2,然后是V1,然后是V3。

注意:考虑到V2和V3与其他节点之间的关系的数量,图没有按正确的左、右顺序描述节点,而V1没有任何祖先。

第二步是:

构造所有虚拟基类(直接和非即时)

  • 使用排名顺序
  • 不要再构造两次

..。

V1和V3实际上都是继承的,V1表示B1,V3表示D,因此它们在这两个步骤中都按照步骤1建立的顺序进行构造。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15885601

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档