第21课 对象的构造顺序

1. 对象的构造顺序

C++中的类可以定义多个对象,那么对象构造顺序是怎样的?

(1)对于局部对象:当程序执行流到达对象的定义语句进行构造

(2)对于堆对象

  ①当程序执行流到达new语句创建对象

  ②使用new创建对象自动触发构造函数的调用

(3)对于全局对象

  ①对象的构造顺序不确定的

  ②不同的编译器使用不同的规则确定构造顺序

 

【实例分析】局部对象的构造顺序  21-1.cpp

#include <stdio.h>

 

class Test

{

private:

    int mi;

 

public:

    Test(int i)

    {

        mi = i;

        printf("Test(int i): %d\n", mi);

    }

 

    Test(const Test& obj)

    {

        mi = obj.mi;

        printf("Test(const Test& obj): %d\n", mi);

    }

 

    ~Test()

    {

       printf("~Test(): %d\n", mi);

    }

};

 

int main()
{

    int i = 0;

    Test a1 = i;//Test(int i):0,执行到这里时构造a1

 

    while(i < 3)

    {

        //注意:a2的作用域只在这个大括号内

        //所以,每执行1次,构造一次a2

        Test a2 = ++i;//Test(int i):1、2、3

    }

 

    goto LabelEnd; //因跳转,所以下列的a不会被构造

 

    if (i < 4)

    {

        Test a = a1;//Test(const Test&):0。但因goto,该对象不会被构造

    }

    else

    {

        Test a(100);//不会被执行,所以不会调用Test(int i)

    }

 

LabelEnd:

 

    return 0;

}

 

 

【编程实验】堆对象的构造顺序  21-2.cpp

#include <stdio.h>

 

class Test

{

private:

    int mi;

 

public:

    Test(int i)

    {

        mi = i;

        printf("Test(int i): %d\n", mi);

    }

 

    Test(const Test& obj)

    {

        mi = obj.mi;

        printf("Test(const Test& obj): %d\n", mi);

    }

 

    ~Test()

    {

       //printf("~Test(): %d\n", mi);

    }

};

 

int main()

{

    int i = 0;

    Test* a1 = new Test(i); //Test(int i):0

 

    while(++i < 10)

        if (i % 2)  //i % 2 !=0

            new Test(i);//Test(int i):1、3、5、7、9

 

    if (i < 4)

    {

        new Test(*a1);//Test(const& Test):0

    }

    else

    {

        new Test(100);//Test(int i):100

    }

 

    return 0;

}

 

 

【实例分析】全局对象的构造顺序  21-3.cpp

//test.h

#ifndef _TEST_H_

#define _TEST_H_

 

#include<stdio.h>

 

class Test

{

public:

    Test(const char* s)

    {

        printf("%s\n", s);

    }

};

 

#endif

 

//t1.cpp

#include "test.h"

 

Test t1("t1");//全局变量

//t2.cpp

#include "test.h"

 

Test t2("t2");//全局变量

//t3.cpp

#include "test.h"

 

Test t3("t3");//全局变量

 

//main.cpp

#include <stdio.h>

#include "test.h"

 

//注意:全局变量会先于main函数执行,因此

//4个全局变量t1-t4会被先构造,再其顺序是不确定的,

//要依赖于编译器。

 

//当构造完全局对象后,会执行main函数,可以发现

//t5是最后一个被构造的。

 

Test t4("t4");//全局变量

 

int main()

{

    Test t5("t5");//局部变量

    return 0;

}

g++编译器的输出结果:

//实验1:g++ main.cpp t1.cpp t2.cpp t3.cpp

//t3->t2->t1->t4->t5:  从右向左

 

//实验2:g++  t3.cpp t1.cpp main.cpp t2.cpp

//t2->t4->t1->t3->t5:  从右向左

 

2.小结

(1)局部对象构造顺序依赖于程序的执行流

(2)堆对象构造顺序依赖于new的使用顺序

(3)全局对象构造顺序是不确定的

posted @ 2018-12-09 16:21  梦心之魂  阅读(142)  评论(0编辑  收藏  举报