zoukankan      html  css  js  c++  java
  • 四种不同对象的生存方式

    东软2012-11月笔试题

    1. <SPAN style="FONT-SIZE: 14px">class Sample  
    2. {  
    3.        int x;  
    4. public:  
    5.       Sample(int a)  
    6.        {  
    7.               x = a;  
    8.               cout << "constructing object: x =" << x << endl;  
    9.        }  
    10. };  
    11.   
    12. void func(int n)  
    13. {  
    14.        static Sample obj(n);  
    15. }  
    16.   
    17. int main()  
    18. {  
    19.        func(1);  
    20.        func(10);  //1   
    21.        return 0;  
    22.   
    23. }  
    24.   
    25. </SPAN>  

               

           [分析]题目的考查点,静态对象的创建及执行。类中的静态对象只会执行一次,这是输出上面结果的原因。

           [扩展分析]此种静态对象的题目之前在360面试的时候被问到过,后来在《深入浅出MFC》基础部分讲解C++重要性质之——C++程序的生与死:兼谈构造函数与析构函数部分的示例很能说明问题。

           笔者对示例稍稍做了扩充,如下:

    1. <SPAN style="FONT-SIZE: 14px">  class CDemo  
    2. {  
    3. public:  
    4.        CDemo(const char* str);  
    5.        ~CDemo();  
    6.        void showObjectName();   //显示对象名。   
    7.   
    8. private:  
    9.        char name[20];  
    10. };  
    11.   
    12.    
    13. CDemo::CDemo(const char* str)  
    14. {  
    15.       strncpy_s(name,str,20);  
    16.        cout << "Constructor called for " << name << " ";  
    17. }  
    18.   
    19. CDemo::~CDemo()  
    20. {  
    21.        cout << "Destructor called for " << name << " ";  
    22. };  
    23.   
    24. void func()  
    25. {  
    26.        CDemo LocalObjectInFunc("LocalObjectInFunc"); //5  //10   
    27.        static CDemo staticObject("StaticObject"); //6      
    28.        CDemo* pHeapObjectInFunc = new CDemo("HeapObjectInFunc"); //7 //11   
    29.        cout << "Inside func" << endl; //8 //12   
    30. //9析构LocalObjectInFunc //13析构LocalObjectInFunc   
    31.   
    32. void CDemo::showObjectName()   //显示对象名   
    33. {  
    34.        cout << name << " ";  
    35. }  
    36.   
    37. CDemo GlobalObject("GlobalObject"); //1   
    38.    
    39. int main()  
    40. {  
    41.        CDemo localObjectInMain("LocalObjectInMain");  //2   
    42.        CDemo* pHeapObjectInMain = new CDemo("HeapObjectInMain"); //3   
    43.    
    44.        cout << "In main, before calling func "//4   
    45.        func();  
    46.        cout << " ";                             //13'   
    47.   
    48.        func();                 //staticObject静态对象已经存在,不再创建!                                       
    49.        cout << " In main, after calling func ";  //14   
    50.   
    51.        //test作用域   
    52.        //staticObject.showObjectName();  //error C2065: “staticObject”: 未声明的标识符   
    53.        //cout << "In main, after GlobalObject.showObjectName(): ";   
    54.        //GlobalObject.showObjectName();   
    55.   
    56.        return 0;  
    57. }//15析构localObjectInMain //16析构staticObject //17析构GlobalObject   
    58.   
    59.   
    60. </SPAN><SPAN style="COLOR: black"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 14px"> </SPAN></SPAN>  
       

    执行结果如下:

         

           [结果分析,引申出四种对象]

     

    生存方式

    执行时机

    消亡时机

    全局(静态)对象

    全局静态存储区 global

    比程序进入点更早,构造函数先被执行;

    程序结束前,其析构函数被执行。

    局部静态对象

    局部静态存储区 local static

    在对象诞生时,其构造函数被执行。(注意,此处只会有一个实例产生,而且固定在内存上(非stack也非heap,它的构造函数在控制权第一次移转到其声明处时被调用。

    程序将结束时(此对象因而将遭致毁灭)其析构函数才被执行,但比全局对象的析构函数更早一步执行

    局部对象

    栈区 stack

    在对象诞生时,其构造函数被执行。(同局部静态对象

    程序流程将离开该对象的存活范围时(以至于该对象将销毁)时,其析构函数被执行。

    new方式产生的局部对象

    堆区 heap

    当对象诞生时,其构造函数被执行。(同局部静态对象、局部对象

    在对象被delete时执行析构函数。(注意,不加deleteheap区空间不会自动释放的,如果程序长期运行,会“吃掉”很多内存,造成结果不可预知。)

     

    [静态对象的深入探究(全局、局部)]

     

    从产生抑制持续到程序结束的那些对象,在这个过程中不会动态的消亡,所以叫静态对象

     

    全局静态对象

    局部静态对象

    1.初始化时机

    1)main函数的代码前进行初始化;

    2)类中静态、全局对象的初始化时机与该类的对象并无关系(强调:出现在类定义中的静态变量语句只是声明,对于要使用的类的静态成员变量,必须还要在类外进行定义,否则使用时会发生链接错误。声明并不会导致空间的分配,只有定义才会使其被生成。也就是如果你对类的静态成员进行了定义,那么它就肯定会被分配空间并初始化。就像全局变量一样);

    初始化发生在函数被调用期间,首次碰到该定义时。

    2.举例(区分全局、局部静态对象)

    1)定义于namespace的对象;

    2)class 函数 file里的static对象;

    3)类中的静态变量和全局变量;

    定义在函数里的为局部静态对象

    3.如何实现的?

    对于non-local静态变量的初始化,编译器实际上是这样实现的。对每个编译文件里需要初始化的静态变量,生成一系列的sti_开头的函数,在里面完成初始化调用语句,然后把这些sti_函数抽取出来,形成一个初始化函数表,然后在__main()函数里调用,然后把这个函数放main里的开头

    而对于local静态变量,为了实现第一次碰到时初始化,附加了一个全局变量,标志该对象是否被初始化,同时在析构时检查这个变量。这样就保证了第一次碰到时初始化,同时只有在执行了构造函数的时候,才会在程序退出时执行对应的析构函数。

  • 相关阅读:
    Siege 3.0 正式版发布,压力测试工具
    Pomm 1.1.2 发布,专为 PG 设计的 ORM 框架
    Whonix 0.5.6 发布,匿名通用操作系统
    国内开源 java cms,Jspxcms 2.0 发布
    EZNamespaceExtensions.Net v2013增加对上下文菜单、缩略图、图标、属性表的支持
    GNU Guile 2.0.9 发布,Scheme 实现
    jdao 1.0.4 发布 轻量级的orm工具包
    OpenSearchServer 1.4 RC4 发布
    Percona Server for MySQL 5.5.3030.2
    Samba 4.0.5 发布
  • 原文地址:https://www.cnblogs.com/davy2013/p/3148933.html
Copyright © 2011-2022 走看看