简体   繁体   English

关于c++中class初始化的问题

[英]Question about class initialization in c++

I am learning c++ and I found something that puzzles me, and it's about the initialization of data members in a class.我正在学习 c++,我发现了一些让我困惑的东西,它是关于 class 中数据成员的初始化。

Given this example:给定这个例子:

class son
{
public:
    son(){
        std::cout << "constructing class son" << std::endl;
    }
};

class father
{
public:
    father(){
        std::cout << "constructing class father" << std::endl;
    }

private: 
    son s;
};

int main( int argc, char *argv[] ){
    father f; 
}

The output is: output 是:

constructing class son
constructing class father

I don't understant why the class son is initialized.我不明白为什么 class son被初始化。 It is supposed that the declaration in father is a declaration, and must be provided a proper initialization in the constructor of father() to initialize, but it appears that it is not needed in the case of class.假设father中的声明是声明,必须在father()的构造函数中提供适当的初始化才能初始化,但class的情况似乎不需要。 Is that true?真的吗?

Take a look at cppreference's description of constructors, especially the section on member initializer lists.看看cppreference 对构造函数的描述,尤其是关于成员初始化器列表的部分。

Before the compound statement that forms the function body of the constructor begins executing, initialization of all direct bases, virtual bases, and non-static data members is finished.在构造函数的 forms 和 function 主体的复合语句开始执行之前,所有直接基、虚拟基和非静态数据成员的初始化都已完成。 Member initializer list is the place where non-default initialization of these objects can be specified.成员初始化器列表是可以指定这些对象的非默认初始化的地方。

Initialization order The order of member initializers in the list is irrelevant: the actual order of initialization is as follows:初始化顺序列表中的成员初始化器的顺序无关紧要:实际的初始化顺序如下:

  1. If the constructor is for the most-derived class, virtual bases are initialized in the order in which they appear in depth-first left-to-right traversal of the base class declarations (left-to-right refers to the appearance in base-specifier lists)如果构造函数用于派生最多的 class,则虚拟基础按照它们在基础 class 声明的深度优先从左到右遍历中出现的顺序进行初始化(从左到右是指在基础中的外观)说明符列表)
  2. Then, direct bases are initialized in left-to-right order as they appear in this class's base-specifier list然后,直接基以从左到右的顺序初始化,因为它们出现在此类的基说明符列表中
  3. Then, non-static data member are initialized in order of declaration in the class definition.然后,按照 class 定义中的声明顺序初始化非静态数据成员。
  4. Finally, the body of the constructor is executed最后执行构造函数的主体

In this case we're really only looking at lines 3 and 4 since there's no inheritance.在这种情况下,我们实际上只查看第 3 行和第 4 行,因为没有 inheritance。

The key takeaway is that every member variable is initialized before the body of the constructor is entered, either default-initialized or according to the values in the member initializer list.关键点是每个成员变量在进入构造函数的主体之前被初始化,无论是默认初始化还是根据成员初始化列表中的值。 Since father::father doesn't have one, it default-initializes s .由于father::father没有,它默认初始化s

To create an object of the class father all its data members (sub-objects) must be created.要创建 class father的 object,必须创建其所有数据成员(子对象)。 So the object s (data member of the type son of the class father ) is created calling the default constructor of the class son .因此 object (class fatherson类型s数据成员)是调用 class son的默认构造函数创建的。

After all sub-objects of the object of the class father have been created the body of the constructor father gets the control.在class父亲的object的所有子对象都被创建之后,构造函数father的主体获得控制权。 That is the body of the constructor of the class father deals with already created data members of the object of the type father .这是 class father的构造函数的主体,处理已创建的father类型的数据成员的数据成员。

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

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