虚拟多继承

  我们知道,一般的,每个类只初始化自己的直接基类。但是在有虚基类存在的时候,这个初始化策略就会失败。因为如果使用这种初始化策略,就会可能多次初始化虚基类,类将沿着包含该虚基类的每个继承路径初始化。所以,为了解决这个重复初始化问题,需要从具有虚基类的类继承的类对初始化进行特殊处理。就是在虚派生中,由最底层派生类的构造函数初始化虚基类。

  下面,我们来看一个例子,其继承关系是这样的,有三个基类,分别是人类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;
}

  程序运行界面:

                                              

  可以看出,在有虚基类的派生类的初始化中,是最先初始化全部的虚基类,然后在按继承顺序顺序初始父类的。

原文地址:https://www.cnblogs.com/venow/p/2742511.html