带基虚类的构造函数执行顺序
1 #include <iostream> 2 3 using namespace std; 4 5 class Base 6 { 7 public: 8 Base(int i){cout <<i<<' '<<"Base"<<endl;} 9 ~Base(){} 10 }; 11 12 class Base1: virtual public Base 13 { 14 public: 15 Base1(int i, int j=0):Base(j){cout<<i<<' '<<"Base1"<<endl;} 16 ~Base1(){} 17 }; 18 19 class Base2: virtual public Base 20 { 21 public: 22 Base2(int i,int j=0):Base(j){cout<<i<<' '<<"Base2"<<endl;} 23 ~Base2(){} 24 }; 25 26 class D:public Base2, public Base1 27 { 28 public: 29 D(int a, int b, int c, int d):mem1(a), mem2(b), Base1(c),Base2(d), Base(a){cout<<b<<' '<<"D"<<endl;} 30 private: 31 Base2 mem2; 32 Base1 mem1; 33 }; 34 35 int main() 36 { 37 D d(1,2,3,4); 38 39 system("pause"); 40 return 0; 41 }
1、最后的派生类中不仅要负责对其直接基类进行初始化,还要负责对虚基类初始化。如:
D(int a, int b, int c, int d):mem1(a), mem2(b), Base1(c),Base2(d), Base(a){cout<<b<<' '<<"D"<<endl;}中的Base(a)是必须得有的。
2、编译系统只执行最后的派生类对虚基类的构造函数的调用,而忽略虚基类的其他派生类对虚基类的构造函数的调用,这就保证了虚基类的数据成员不会被多次初始化。
3、派生类构造函数初始化顺序,基类构造函数(多个基类,按声明的先后顺序)、子对象构造函数(多个子对象,按定义的先后顺序)、派生类构造函数。
输出结果为: