多继承中构造函数调用的顺序

Ank*_*kur 6 c++ oop constructor multiple-inheritance

我试图找到很多,如果只有一个类在多重继承中变成虚拟的话?在这种情况下,构造函数调用的行为对我来说并不清楚.比如说代码 -

#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;
}
Run Code Online (Sandbox Code Playgroud)

此代码的输出如下

grandfather
parent1 
grandfather
parent2
child
Run Code Online (Sandbox Code Playgroud)

但是在上面的代码中如果我们改变这个

class parent1:virtual public grand{
public:
    parent1(){cout<<"parent1 "<<endl;}
};
class parent2: public  grand{
public:
    parent2(){cout<<"parent2"<<endl;}
};
Run Code Online (Sandbox Code Playgroud)

对此

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;}
};
Run Code Online (Sandbox Code Playgroud)

输出显示为

grandfather
grandfather    //why parent1 constructor is not called here?
parent1 
parent2
child
Run Code Online (Sandbox Code Playgroud)

我关心的是为什么在祖父之后没有调用parent1构造函数?

Jea*_*nès 7

标准说[C++ 11第12.6.2/10节]:

在非委托构造函数中,初始化按以下顺序进行:

- 首先,仅对于派生程度最高的类的构造函数,虚拟基类按照它们出现在基类的有向无环图的深度优先从左到右遍历的顺序进行初始化,其中"left-to- right"是派生类base-specifier-list中基类出现的顺序.

- 然后,直接基类按声明顺序初始化,因为它们出现在base-specifier-list中(无论mem-initializers的顺序如何).

- 然后,非静态数据成员按照它们在类定义中声明的顺序进行初始化(同样不管mem-initializers的顺序如何).

- 最后,执行构造函数体的复合语句.

因此,您的虚拟基类始终首先构建...这在虚拟基类共享的情况下非常重要.