C++学习之路: 构造函数详解与初始化列表

引言:这是C++对象内存分配的基础,为防止忘记。

看一个类包含其他类时是如何构造的。

#include <iostream>
using namespace std;


class Object
{
public:
    Object()
    {
        cout << "Object.." << endl;
    }
    ~Object()
    {
        cout << "~Object.." << endl;
    }
};



class Container
{
public:
    Container()
    {
        cout << "Container...." << endl;
    }
    ~Container()
    {
        cout << "~Container..." << endl;
    }
private:
    Object obj_;
};

int main(void)
{
    Container c;
    return 0;
}

Control+F5

命令行结果:

C++学习之路: 构造函数详解与初始化列表

构造顺序 为包含关系 从内向外依次构造, 析构则相反。

变换一下构造函数,我们看看和初始化列表有没有关系。

 1 #include <iostream>
 2 using namespace std;
 3 
 4 
 5 class Object
 6 {
 7 public:
 8     Object(int num) : num_(num)
 9     {
10         cout << "Object.." << num_ << "..."<< endl;
11     }
12     ~Object()
13     {
14         cout << "Object.." << num_ << "..." << endl;
15     }
16 private:
17     int num_;
18 };
19 
20 
21 
22 class Container
23 {
24 public:
25     Container(int num1=0, int num2=0) : obj1_(num1), obj2_(num2)
26     {
27         cout << "Container...." << endl;
28     }
29     ~Container()
30     {
31         cout << "~Container..." << endl;
32     }
33 private:
34     Object obj1_;
35     Object obj2_;
36 };
37 
38 int main(void)
39 {
40     Container c(10, 20);
41     return 0;
42 }

打印结果:

C++学习之路: 构造函数详解与初始化列表

我们将初始化列表调换一下顺序。

#include <iostream>
using namespace std;


class Object
{
public:
    Object(int num) : num_(num)
    {
        cout << "Object.." << num_ << "..."<< endl;
    }
    ~Object()
    {
        cout << "Object.." << num_ << "..." << endl;
    }
private:
    int num_;
};



class Container
{
public:
    Container(int num1 = 0, int num2 = 0) :  obj2_(num2) ,obj1_(num1)   //已经调换顺序
    {
        cout << "Container...." << endl;
    }
    ~Container()
    {
        cout << "~Container..." << endl;
    }
private:
    Object obj1_;
    Object obj2_;
};

int main(void)
{
    Container c(10, 20);
    return 0;
}

打印结果:

C++学习之路: 构造函数详解与初始化列表

所以结论是:

构造顺序只与 成员对象定义的顺序有关,它们的内存从一开始就确定了,与初始化列表没有关系

只要obj1_定义在obj2_前面,构造顺序也一定是先构造obj1_;