我试图找到很多如果只有一个类在多重继承中变为虚拟会怎么样? 在这种情况下,构造函数调用的行为对我来说并不清楚。 比如说代码 -
#include<iostream>
using namespace std;
class grand{
public:
grand(){cout<<"grandfather"<<endl;}
};
class parent1:virtual public grand{ //virtual used only here
public:
parent1(){cout<<"parent1 "<<endl;}
};
class parent2: public grand{
public:
parent2(){cout<<"parent2"<<endl;}
};
class child:public parent1,public parent2{
public:
child(){cout<<"child"<<endl;}
};
int main() {
child s;
return 0;
}
此代码的输出为
grandfather
parent1
grandfather
parent2
child
但是在上面的代码中我们改变了这个
class parent1:virtual public grand{
public:
parent1(){cout<<"parent1 "<<endl;}
};
class parent2: public grand{
public:
parent2(){cout<<"parent2"<<endl;}
};
到这个
class parent1:public grand{ //virtual removed from here
public:
parent1(){cout<<"parent1 "<<endl;}
};
class parent2:virtual public grand{ //virtual is added here
public:
parent2(){cout<<"parent2"<<endl;}
};
输出显示为
grandfather
grandfather //why parent1 constructor is not called here?
parent1
parent2
child
我关心的是为什么在祖父之后没有调用parent1构造函数?
答案 0 :(得分:7)
标准说[C ++ 11第12.6.2 / 10节]:
在非委托构造函数中,初始化继续进行 以下顺序:
- 首先,仅适用于派生程度最高的类的构造函数, 虚拟基类按照它们出现在的顺序进行初始化 深度优先从左到右遍历有向无环图 基类,其中“从左到右”是出现的顺序 派生类base-specifier-list中的基类。
- 然后,直接基类按声明顺序初始化为 它们出现在base-specifier-list中(无论顺序如何 MEM-初始化)。
- 然后,按照它们的顺序初始化非静态数据成员 在类定义中声明(再次无论顺序如何 MEM-初始化)。
- 最后,执行构造函数体的复合语句。
因此,您的虚拟基类始终首先构建...这对于虚拟基类共享非常重要。