根据上面的规则,可以看出,先构造的是虚继承基类的构造函数,并且是按照深度优先,从左往右构造。因此,我们需要将继承结构划分层次。显然上面的代码可以认为是4层继承结构。其中顶层的是B1,B2类。第二层是V1,V2,V3。第三层是D1,D2.底层是X。而D1虚继承V1,D2虚继承V2,且D1和D2在同一层。所以V1先构造,其次是V2.在V2构造顺序中,B1先于B2.虚基类构造完成后,接着是直接基类子对象构造,其顺序为D1,D2.后为成员子对象的构造,顺序为声明的顺序。构造完毕后,开始按照构造顺序执行构造函数体了。所以其终的输出结果为:

  B1::B1()!<
  V1::V1()!<
  B1::B1()!<
  B2::B2()!<
  V2::V2()!<
  D1::D1()!<
  B3::B3()!<
  D2::D2()!<
  M1::M1()!<
  M2::M2()!<

  从结果也可以看出其构造顺序完全符合上面的标准。而在结果中,可以看到B1重复构造。还是因为没有按照要求使用virtual继承导致的结果。要想只构造B1一次,可以将virtual全部改在B1上,如下面的代码:

class B1
{
public:
    B1(){cout<<"B1::B1()!<"<<endl;}
    void f() {cout<<"i'm here!"<<endl;}
};

class V1: virtual public B1   //public修改为virtual
{
public:
    V1(){cout<<"V1::V1()!<"<<endl;}
};

class D1:  public V1
{
public:
    D1(){cout<<"D1::D1()!<"<<endl;}
};

class B2
{
public:
    B2(){cout<<"B2::B2()!<"<<endl;}
};

class B3
{
public:
    B3(){cout<<"B3::B3()!<"<<endl;}
};

class V2:virtual public B1, public B2 //public B1修改为virtual public B1
{
public:
    V2(){cout<<"V2::V2()!<"<<endl;}
};

class D2: public V2, public B3
{
public:
    D2(){cout<<"D2::D2()!<"<<endl;}
};

class M1
{
public:
    M1(){cout<<"M1::M1()!<"<<endl;}
};

class M2
{
public:
    M2(){cout<<"M2::M2()!<"<<endl;}
};

class X:public D1, public D2
{
    M1 m1;
    M2 m2;
};