我们知道,一般的,每个类只初始化自己的直接基类。但是在有虚基类存在的时候,这个初始化策略就会失败。因为如果使用这种初始化策略,就会可能多次初始化虚基类,类将沿着包含该虚基类的每个继承路径初始化。所以,为了解决这个重复初始化问题,需要从具有虚基类的类继承的类对初始化进行特殊处理。就是在虚派生中,由最底层派生类的构造函数初始化虚基类。
下面,我们来看一个例子,其继承关系是这样的,有三个基类,分别是人类Human、行为Behavior和非人类行为NonhumanFeature,男人Man和女人Woman公有虚拟继承自Human,人类行为HumanBehavior公有虚拟继承行为Behavior,Japanese公有继承男人Man、女人Woman和人类行为HumanBehavior以及公有虚拟继承非人类行为NonhumanFeature。
下面是UML图:
简单代码如下:
//人类---基类 class Human { public: Human() { cout<<"Construct Human"<<endl; } }; //男人---公有虚拟继承Human class Man : virtual public Human { public: Man() { cout<<"Construct Man"<<endl; } }; //女人---公有虚拟继承Human class Woman : virtual public Human { public: Woman() { cout<<"Construct Woman"<<endl; } }; //行为---基类 class Behavior { public: Behavior() { cout<<"Construct Behavior"<<endl; } }; //人类行为---公有虚拟继承Behavior class HumanBehavior : virtual public Behavior { public: HumanBehavior() { cout<<"Construct HumanBehavior"<<endl; } }; //非人类特征---基类 class NonhumanFeature { public: NonhumanFeature() { cout<<"Construct NonhumanFeature"<<endl; } }; //公有继承Man、Man和HumanBehavior, 公有虚拟继承NonhumanBehavior class Japanese : public Man, public Woman, public HumanBehavior, public virtual NonhumanFeature { public: Japanese() { cout<<"Construct Japanese"<<endl; } }; int _tmain(int argc, _TCHAR* argv[]) { Japanese jj; return 0; }
程序运行界面:
可以看出,在有虚基类的派生类的初始化中,是最先初始化全部的虚基类,然后在按继承顺序顺序初始父类的。