我偶然发现了这个代码示例:
#include <iostream>
using namespace std;
class A {
int x;
public:
A() { x = 1; cout << "A"; }
};
class B : virtual public A {
int y;
public:
B() { y = 2; cout << "B"; }
};
class C : virtual public B, virtual public A {
int z;
public:
C() { z = 3; cout <<"C"; }
};
class D : public A, public B, public C {
int t;
public:
D() { t = 4; cout << "D"; }
};
int main()
{
D d;
return 0;
}
This code prints ABABCD
我不明白为什么。我认为它会为A
打印D : public A
,然后AB
打D : public B
,ABC
打D : public C
,然后D
打印A
,但似乎{{1}}只打印两次。这是如何工作的?
答案 0 :(得分:8)
基础的构造顺序是(忽略虚拟基础)从左到右,因为它们是在继承关系中键入的。添加虚拟基础后,将以深度优先从左到右的方式初始化 first (在任何非虚拟基础之前)。
现在这应解释输出。
D:A,B,C
A没有虚拟基础,B有一个虚拟A基础,所以这是第一次初始化:“A”。然后C有一个虚拟B基,所以这是下一个被初始化。此时,A虚拟子对象已经初始化,因此只有B构造函数被评估为“AB”。此时,构建了所有虚拟基础并构建了非虚拟基础,首先是A,然后是B,然后是C,然后是完整类型D,产生“ABABCD”。虚拟子对象都已构造完成,因此不会再构造它们。
要记住一些事情。虚拟基础仅与愿意共享它的其他子对象共享(即将其作为虚拟基础)。在完整对象中共享虚拟基础的次数没有限制(即A虚拟基础多次共享,包括来自不同的B子对象)