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


posted @ 2017-06-04 17:14  小怪兽&奥特曼  阅读(911)  评论(0编辑  收藏  举报