简体   繁体   English

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

[英]How derived class constructor calls base class constructor internally

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

Class A and B have default constructors. 类A和B具有默认构造函数。 And I know that class A default constructor will be called first and then B default constructor. 而且我知道类A的默认构造函数将首先被调用,然后是B的默认构造函数。 But the question is how that happens internally? 但是问题是这种情况在内部如何发生? Do data members get constructed in the inheritance order? 数据成员是否按继承顺序构造? How/where compiler puts call to base ctor from dervied ctor? 编译器如何/在何处放置来自派生ctor的对base ctor的调用?

Basically base classes are initialized first, then data members in declaration order. 基本上,首先初始化基类,然后按声明顺序初始化数据成员。 One exception is for virtual base classes, which are initialized first and from the most derived class. 虚拟基类是一个例外,虚拟基类是首先初始化的,并且是从最派生的类初始化的。 Another exception is for delegating constructors. 另一个例外是委派构造函数。


Standardeese: in C++11 this is specified by §12.6.2/10: 简体中文:在C ++ 11中,这由§12.6.2/ 10指定:

In a non-delegating constructor, initialization proceeds in the following order: 在非委托构造函数,以下列顺序进行初始化:

  • First, and only for the constructor of the most derived class (1.8), virtual base classes are initialized in the order they appear on a depth-first left-to-right traversal of the directed acyclic graph of base classes, where “left-to-right” is the order of appearance of the base classes in the derived class base-specifier-list . 首先,并且仅对于大多数派生类(1.8)的构造函数而言,虚拟基类按照它们在基类有向无环图的深度优先从左到右遍历时出现的顺序进行初始化,其中“左- “从右到右”是基类在派生类base-specifier-list中的出现顺序。
  • Then, direct base classes are initialized in declaration order as they appear in the base-specifier-list (regardless of the order of the mem-initializers ). 然后,直接基类按照它们出现在base-specifier-list中的顺序进行初始化 (与mem-initializers的顺序无关)。
  • Then, non-static data members are initialized in the order they were declared in the class definition (again regardless of the order of the mem-initializers ). 然后,非静态数据成员按照它们在类定义中声明的顺序进行初始化(同样,无论mem-initializer的顺序如何)。
  • Finally, the compound-statement of the constructor body is executed. 最后,执行构造函数主体的复合语句

[ Note: The declaration order is mandated to ensure that base and member subobjects are destroyed in the reverse order of initialization. [ 注意:声明顺序是强制执行的,以确保以相反的初始化顺序销毁基础和成员子对象。 —end note ] —尾注 ]


As to how this works internally, a common technique is that a constructor calls its associated base and ordinary member constructors. 关于它在内部如何工作,一种常见的技术是构造函数调用其关联的基本和普通成员构造函数。 If you ignore virtual bases and constructor delegation, and consider instantiation of a class T, then when you instantiate T the first that happens is that a T constructor is called. 如果忽略虚拟基和构造函数委托,并考虑实例化类T,则在实例化T时,首先发生的是调用T构造函数。 But this is not yet initialization of the T instance itself. 但这还不是T实例本身的初始化。 The execution is still in the memory initializer list of that constructor. 执行仍在该构造函数的内存初始化器列表中。 Here it calls the various base and non-base member constructors (where the same happens, recursively). 在这里,它调用了各种基本和非基本成员构造函数(递归发生在相同的地方)。 Finally the constructor body is executed. 最终,构造函数体被执行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM