C++对象的生成和消亡时刻分析
对于不同性质的C++对象的生成和消亡时间是不同,比如全局对象、静态对象、局部对象等;
1. 对于全局对象,C++规定 全局对象的构建将比程序进入点(main函数,WinMain函数)更早,全局类对象的构造函数都是在main函数之前完成调用的;
2. 对于静态数据成员和普通类型全局变量,是在程序进入前完成初始化,如果没有设置默认值,其初始值为0,或者空,
测试结果如下:
class CPerson { public: CPerson() { printf("Cperson Construct...\n"); } ~CPerson() { printf("Cperson Deconstruct...\n"); } public: static int m_nAge; }; static CPerson s_Person; CPerson theApp; //静态成员数据初始化是在类外初始化的,即使m_nAge是private也能初始化成功 int CPerson::m_nAge = 10; int g_a = 10; int _tmain(int argc, _TCHAR* argv[]) { printf("_tmain is begin...\n"); printf("m_nAge = %d\n",CPerson::m_nAge); printf("g_a = %d\n",g_a); printf("_tmain will be return...\n"); return 0; }
运行结果:
需要说明的是,对于有的C++对象的消亡时刻分析,需要借助调试器进行,通过跟踪程序的执行过程才可以得到准确的结论。
现在总结静态全局对象、静态局部对象、局部对象、new全局对象、全局对象的生成和消亡时刻;
static CPerson s_Person; //全局对象的构造函数main函数执行前调用 //全局对象的析构函数在return执行以后被调用 CPerson theApp; //全局对象的构造函数main函数执行前调用 //全局对象的析构函数在return执行以后被调用 int main() { /** * CPerson test; * 局部对象的构造函数在程序执行到这里时调用 * 局部对象的析构函数在return执行以前被调用 */ /** * CPerson *test = new CPerson; * 构造函数在程序执行到这里时调用 * delete test; * new生成的对象的析构函数在delete执行以后调用 */ /** * static CPerson test; * 局部静态对象的构造函数在程序执行到这里时调用 * 局部静态对象的析构函数在return执行以后被调用 */ { /** * CPerson test; * 局部对象的构造函数在程序执行到这里时调用 * test离开此作用域就会调用析构函数 */ } return 0; }
可见:全局对象的构造函数会在main函数之前执行。
在大多数的实现方式里,核心会运行专门的启动代码,启动代码会在启动main()之前完成所有的初始化工作,这其中当然包括了全局对象的初始化。这个所谓的启动代码就是Runtime函数库的Startup代码。
在程序执行时,系统会先调用Startup,完成函数库初始化、进程信息设立、I/O stream产生,以及对static对象的初始化等动作。然后Startup调用main()函数,把控制权交给main()函数。main()函数执行完毕,控制权交回给Startup,进行反初始化动作。
可以看看CRT的代码,里面的CRT初始化过程包含所有全局变量的构造,这些全局变量被编译器放到一个链表中了,CRT初始化时读取链表依次执行回调函数(就是构造函数),然后才执行MAIN入口点函数。
参考文章:http://www.cnblogs.com/lgh1992314/p/6616361.html