• C++对象的生成和消亡时刻分析


    对于不同性质的C++对象的生成和消亡时间是不同,比如全局对象、静态对象、局部对象等;


    1. 对于全局对象,C++规定 全局对象的构建将比程序进入点(main函数,WinMain函数)更早,全局类对象的构造函数都是在main函数之前完成调用的;

    2. 对于静态数据成员和普通类型全局变量,是在程序进入前完成初始化,如果没有设置默认值,其初始值为0,或者空,


    测试结果如下:

    class CPerson
    {
    public:
        CPerson()
        {
            printf("Cperson Construct...
    ");
        }
        ~CPerson()
        {
            printf("Cperson Deconstruct...
    ");
    
        }
    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...
    ");
        printf("m_nAge = %d
    ",CPerson::m_nAge);
        printf("g_a = %d
    ",g_a);
        printf("_tmain will be return...
    ");
        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


  • 相关阅读:
    自实现简单线程池
    Object obj=new Object()的内存引用
    Java运行时内存模式学习
    C/C++、C#、JAVA(一):代码模板与库代码的引入
    java GUI 快速入门
    C# 一些类名的后缀及其意义
    ASP.NET Core 中jwt授权认证的流程原理
    .NET Core 获取主机运行资源的库
    .NET Core 获取程序运行环境信息与反射的应用
    【5分钟+】计算机系统结构-数据表示
  • 原文地址:https://www.cnblogs.com/jinxiang1224/p/8468273.html
Copyright © 2020-2023  润新知