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

时间:2014-06-18 09:09:55

标签: c++ constructor

#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默认构造函数。但问题是内部是如何发生的?数据成员是否以继承顺序构建?编译器如何/在何处从dervied ctor调用base ctor?

1 个答案:

答案 0 :(得分:2)

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


Standardeese:在C ++ 11中,这由§12.6.2/ 10指定:

  

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

     
      
  • 首先,仅针对派生程度最高的类(1.8)的构造函数,初始化虚拟基类   它们出现在基类的有向无环图的深度优先从左到右遍历中的顺序,   其中“从左到右”是派生类 base-specifier-list 中基类出现的顺序。
  •   
  • 然后,直接基类按声明顺序初始化,因为它们出现在 base-specifier-list 中   (无论 mem-initializers 的顺序如何。)
  •   
  • 然后,按照在类定义中声明的顺序初始化非静态数据成员   (再次无论 mem-initializers 的顺序如何)。
  •   
  • 最后,执行构造函数体的复合语句
  •   
     

[注意:声明命令的目的是确保基础和成员子对象在   初始化的逆序。 -end note ]


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