对象的构造顺序(十六)
在 C++ 中的类可以定义多个对象,那么对象构造的顺序是怎样的呢?对于局部对象:当程序执行流到达对象的定义语句时进行构造。我们以代码为例进行分析
#include<stdio.h>classTest{private:intmi;public:Test(inti){mi=i;printf("Test(inti):%d\n",mi);}Test(constTest&obj){mi=obj.mi;printf("Test(constTest&obj):%d\n",mi);}};intmain(){inti=0;Testa1=i;//Test(inti):0while(i<3){Testa2=++i;//Test(inti):1,2,3}if(i<4){Testa=a1;//Test(constTest&obj):0}else{Testa(100);}return0;}
我们按照程序的执行流可以看到先是执行对象 a1 的创建,接着是对象 a2 的创建 3 次,最后是对象 a 的拷贝构造。我们看看结果是否如我们所分析的那样
我们看到局部对象的构造顺序确实如我们所想的那样。如果我们使用 goto 语句呢,我们看个代码
#include<stdio.h>classTest{private:intmi;public:Test(inti){mi=i;printf("Test(inti):%d\n",mi);}Test(constTest&obj){mi=obj.mi;printf("Test(constTest&obj):%d\n",mi);}intgetMI(){returnmi;}};intmain(){inti=0;Testa1=i;//Test(inti):0while(i<3){Testa2=++i;//Test(inti):1,2,3}gotoEnd;Testa(100);End:printf("a.mi=%d\n",a.getMI());return0;}
我们来编译看看
编译直接出错,因为我们使用了 goto 语句,导致程序的执行流出错了。
接下来我们来看看堆对象的构造顺序,当程序执行流到达 new 语句时创建对象,使用 new 创建对象将自动触发构造函数的调用。
下来还是以代码为例来分析堆对象的构造顺序
#include<stdio.h>classTest{private:intmi;public:Test(inti){mi=i;printf("Test(inti):%d\n",mi);}Test(constTest&obj){mi=obj.mi;printf("Test(constTest&obj):%d\n",mi);}intgetMI(){returnmi;}};intmain(){inti=0;Test*a1=newTest(i);//Test(inti):0while(++i<10)if(i%2)newTest(i);//Test(inti):1,3,5,7,9if(i<4)newTest(*a1);elsenewTest(100);//Test(inti):100return0;}
我们看看是否如我们所注释的那样执行的
确实,堆对象的构造顺序是跟 new 关键字有关系的。下来我们来看看全局对象,对象的构造顺序是不确定的,不同的编译器使用不同的规则来确定构造顺序。还是以代码为例来进行验证
test.h 源码
#ifndef_TEST_H_#define_TEST_H_#include<stdio.h>classTest{public:Test(constchar*s){printf("%s\n",s);}};#endif
t1.cpp 源码
#include"test.h"Testt1("t1");
t2.cpp 源码
#include"test.h"Testt2("t2");
t3.cpp 源码
#include"test.h"Testt3("t3");
test.cpp 源码
#include"test.h"Testt4("t4");intmain(){Testt5("t5");return0;}
我们来编译看看结果
这个结果貌似跟我们指定编译的顺序有关系,我们再来看看BCC编译器呢
再来试试 VS2010
以前博主在书上和视频中看到过全局对象的构造顺序是不确定的,可能现在的编译器做了优化吧。反正我们记住就可以了,尽量避免使用全局对象。通过对对象的构造顺序的学习,总稽核如下:局部对象的构造顺序依赖于程序的执行流;堆对象的构造顺序依赖于 new 的使用顺序;全局对象的构造顺序是不确定的
欢迎大家一起来学习 C++ 语言,可以加我QQ:243343083。
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。