在类派生自三个基类的"diamond problem"中,构造顺序是什么?
What is the construction order in a "diamond problem" where a class is derived from three base classes?
下面是我所询问的示例代码。输出将是XXbBACY,但我不明白为什么。
#include <iostream>
using namespace std;
class X {
public:
X() { cout << 'X'; }
X(char c) { cout << 'X' << c; }
};
class A : virtual X {
public:
A() : X('a') { cout << 'A'; }
};
class B : X {
public:
B() : X('b') { cout << 'B'; }
};
class C : virtual X {
public:
C() : X('c') { cout << 'C'; }
};
class Y : A, virtual B, C {
public:
Y() { cout << 'Y'; }
~Y() {}
};
int main() {
Y y;
return 0;
}
根据我的理解,当我们创建类y的对象y时,因为不是所有的基类都是从类X(特别是B(派生的,所以y中会有3个类X的实例。
构造对象y时调用的第一个构造函数将是类B的构造函数,因为它实际上是从类y派生的,但在构造类B之前,必须创建类X的实例,因为B() : X('b') { cout << 'B'; }
是类B的默认构造函数,X(char c) { cout << 'X' << c; }
将在类X中调用。它将打印Xb。现在我们返回到类B,默认构造函数将打印B,然后返回到类Y
现在,类A和类C的一个实例将以类似的方式构建,留下一个输出:XbBXaAXcCY
我的理解似乎完全错误,因为输出是XXbBACY,这怎么可能呢?
施工顺序总是这样:
- 首先是所有(直接或间接(虚拟基,顺序为深度优先声明顺序。显然,任何一种类型中最多只能有一种
- 接下来,按声明顺序排列非虚拟基
- 按申报顺序排列的所有其他成员
- 最后,ctor主体。现在,您可以安全地直接或间接调用虚拟函数,它们将根据当前运行的ctor进行解析
在您的情况下,这意味着:
- CCD_ 3与CCD_
virtual B
来自Y::B
:
(第一步:X
来自Y::B::X
。(- CCD_ 9从CCD_。
X
虚拟基地已经完成 - CCD_ 12从CCD_。
X
虚拟基地已经完成
销毁顺序颠倒了这一点。
相关文章:
- 无法让 Assimp 在 Windows " linker problem" 上运行?(与2019年相比)
- 当我想扩展当前应用程序的功能时,出现DIAMOND情况
- 虚拟表正是为Diamond继承中的哪个类创建的
- C++ Winsock unicode problem
- 具有多态性的"dreaded diamond"
- QT QStackedLayout problem
- Problem with Android ndk
- OpenGL SuperBible header problem
- 没有数据成员的Diamond(多重继承)
- WaitForSingleObject problem
- Anderson tree problem
- for_each C++ Problem
- for循环-C++Diamond控制台输出问题
- Getline problem
- CDialog ShowWindow problem
- SLOT problem / C++
- BitBlt Problem GDI
- Problem with C# COM
- eof problem c++
- Problem with Euler 27