我试图找到很多东西,如果只有一个类在多重继承中成为虚拟的呢?在这种情况下,构造函数调用的行为对我来说还不清楚。例如说代码-
#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构造函数?
标准说[C ++ 11第12.6.2 / 10节]:
在非委托构造函数中,初始化按以下顺序进行:
—首先,并且仅对于大多数派生类的构造函数而言,虚拟基类按照它们在基类的有向无环图的深度优先从左到右遍历时出现的顺序进行初始化,其中“从左到右”右”是基类在派生类base-specifier-list中的出现顺序。
—然后,直接基类按照它们出现在base-specifier-list中的声明顺序进行初始化(与mem-initializers的顺序无关)。
—然后,非静态数据成员按照它们在类定义中声明的顺序进行初始化(同样,无论mem-initializer的顺序如何)。
—最后,执行构造函数主体的复合语句。
因此,始终要首先构建您的虚拟基类...对于虚拟基类共享,这确实很重要。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句