派生类构造函数如何在内部调用基类构造函数

How derived class constructor calls base class constructor internally

本文关键字:构造函数 调用 基类 在内部 派生      更新时间:2023-10-16
#include <iostream>
#include <string>
using namespace std;
class A
{
    private:
        int ai;
        string as;
};
class B : public A
{
    private:
        int bi;
        string bs;
};

int main()
{
    B bob;
    return 0;
}

类A和B有默认构造函数。我知道类A的默认构造函数会先被调用然后是类B的默认构造函数。但问题是这是如何在内部发生的?数据成员是否按照继承顺序构造?编译器如何/在哪里从派生函数调用基函数?

基本上是先初始化基类,然后按声明顺序初始化数据成员。一个例外是虚拟基类,它首先从最派生的类初始化。另一个例外是委托构造函数。


标准:在c++ 11中,这由§12.6.2/10:

规定

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

  • 首先,并且仅对最派生类的构造函数(1.8)初始化虚基类它们在基类的有向无环图从左到右的深度优先遍历中出现的顺序,其中"从左到右"是派生类base- specific -list中基类的出现顺序。
  • 然后,直接基类按照它们出现在base-specifier-list中的声明顺序初始化。(不管mem初始化式的顺序)。然后,按照在类定义中声明的顺序初始化非静态数据成员(同样,不管mem初始化式的顺序)。最后,执行构造函数体的复合语句

[注意:声明顺序是强制的,以确保基子对象和成员子对象在初始化的反向顺序。 -end note]


至于这在内部是如何工作的,一种常用的技术是构造函数调用其关联的基和普通成员构造函数。如果忽略虚拟基和构造函数委托,并考虑类T的实例化,那么在实例化T时,首先发生的是调用T构造函数。但这还不是T实例本身的初始化。执行仍然在该构造函数的内存初始化列表中。在这里,它调用各种基和非基成员构造函数(在这里也会递归地发生相同的情况)。最后执行构造函数体。