
嗨,如您所见,示例中的构造顺序是:- U1 U2 Y X V2 V1 V3 V4 B1 B2 D
我了解到:U1 U2 Y X被初始化是因为V2是对D的第一个直接虚拟继承,为了初始化它,需要初始化这些第一个U1 U2 Y。在此之后,V2被初始化,但是为什么V1在V3之前被初始化,尽管有来自V3的直接虚拟继承。
请忽略节点和箭头的数目,并注意红色箭头是非虚拟继承,黑色箭头是虚拟的。
注:原始文件可找到http://webcourse.cs.technion.ac.il/236703/Winter2012-2013/ho/WCFiles/12%2520-%2520Multiple%2520Inheritance%2520-%2520c%2B%2B11.pdf。
发布于 2013-04-08 19:18:31
这是我对这个例子的理解。它符合建筑订单,所以我相信它是正确的。不过,我不确定。
首先,箭头的数量很重要,因为它们告诉您定义基类的顺序。仅以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 {X {U1, U2}, Y}, B1 {V1, V3, V4}, B2}下一部分是查找非虚拟基类并对我的列表进行调整。
关于这一点,还有一点:考虑到您的问题,我希望您也认为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也是非虚拟的,如果它不是我列表中的最后一个,就需要考虑它。
这给了我一个令我满意的命令。唯一的问题是,我在基类之前列出了派生类,而且我们知道基类是先构造的。剩下的两个地方都是问题所在
因此,我将调整我的列表以移动这两项,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 2012构建时调用的顺序相匹配。
发布于 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建立的顺序进行构造。
https://stackoverflow.com/questions/15885601
复制相似问题