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

Sequence of constructor calls in multiple inheritance

本文关键字:函数调用 多重继承      更新时间:2023-10-16

我试图发现很多,如果在多重继承中只有一个类是虚拟的怎么办?在这种情况下,我不清楚构造函数调用的行为。让我们说示例代码-

#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;
}

此代码的输出为

grandfather
parent1 
grandfather
parent2
child

但是在上面的代码中,如果我们更改它

class parent1:virtual public grand{
public:
    parent1(){cout<<"parent1 "<<endl;}
};
class parent2: public  grand{
public:
    parent2(){cout<<"parent2"<<endl;}
};

对此

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;}
};

输出显示为

grandfather
grandfather    //why parent1 constructor is not called here?
parent1 
parent2
child

我担心的是为什么 parent1 构造函数不以祖父的名字命名?

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

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

— 首先,并且仅对于派生最多的类的构造函数, 虚拟基类按照它们在 有向无环图的深度优先从左到右遍历 基类,其中"从左到右"是 派生类基说明符列表中的基类。

— 然后,直接基类按声明顺序初始化为 它们出现在基本说明符列表中(无论 内存初始化器(。

— 然后,非静态数据成员按其顺序初始化 在类定义中声明(同样,无论 内存初始化器(。

— 最后,执行构造函数主体的复合语句。

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