• (转-经典-数据段)C++回顾之static用法总结、对象的存储,作用域与生存期


    转自:https://blog.csdn.net/ab198604/article/details/19158697
    相关知识补充:https://www.cnblogs.com/rednodel/p/9300729.html


      在C语言中,static的用法非常简单,只有两种:

            (1)用于函数内部修饰变量,即函数内的静态变量。这种变量的生存期大于函数,使得函数具有一定的“状态”,使用静态变量的函数一般是不可重入的,也不是线程安全的。如strtok(3).

            (2) 用在文件级别,函数体外, 修饰变量或函数,表示该变量或函数只在本文件内可见。其它文件看不到也访问不到该变量或函数。

            在C++中,保留了C的上面用法,除此以外,还有以下两种新用法:

            (1) 用于修饰类的数据成员,即所谓的“静态成员”, 这种数据成员的生存期大于类对象(实例),静态数据成员是每个class有一份, 普通数据成员是每个类对象(实例)有一份。

            (2) 用于修饰类的成员函数,即所谓的“静态成员函数”,这种成员函数也只能访问静态成员和其它静态成员函数,不能访问非静态成员与非静态成员函数。

            关于对象的作用域与生存期

            需要明确一点的是,作用域与生存期在某些情况下是不一致的,它们并不等同。下面是存储器模型:

            

            程序在存储器中按上述模型存放,它有代码段,数据段,堆和栈之分。代码段是只读的,数据段分为未初始化的数据段.bss(block started by symbol)和已初始化的数据段.data段。未初始化数据段.bss的特征是在可执行文件中不占空间,在运行时才分配空间,而.data段在编译期间就被初始化,在可执行文件中占据空间。

            对于全局变量

            如int a; 未被初始化,所以它存放在.bss段中

            如int a = 100; 已初始化,故它存放在.data段中.

            对于静态全局变量

            如static int a; 未被初始化,它存放在.bss段中

            如static int a = 100; 已初始化,故它存放在.data段中

            对于静态局部变量

            如下所示:

    [cpp] view plain copy
     
    1. int main()  
    2. {  
    3.     ...  
    4.     {  
    5.         //下面a,b的作用域在{}内,生存期在整个程序的生存期之内  
    6.         static int a; //存储于.bss段中  
    7.         static int b = 100; //存储于data段中。  
    8.     }  
    9. }  


      

            对于全局对象与静态全局对象

            如Test g(10); static Test g(10); 它们存放在data段中,但运行时,对象的构造函数都是先于main函数调用的,在main函数结束后自动调用析构函数销毁

            对于局部对象

    [cpp] view plain copy
     
    1. int main()  
    2. {  
    3.     ....  
    4.     Test t(10);//局部对象在栈上创建,生存期在main块作用域范围之内,main结束后自动调用析构函数销毁  
    5. }  

            如果在以下情况,它将在{}作用域结束后就自动调用析构函数销毁

    [cpp] view plain copy
     
    1. int main()  
    2. {  
    3.     ...  
    4.     {  
    5.         Test t(10);  //在栈上创建,作用域在{}  
    6.     }//退出{}后就自动销毁对象  
    7. }  

            

            对于静态局部对象

            如下:

    [cpp] view plain copy
     
    1. int main()  
    2. {  
    3.     ...  
    4.     {  
    5.         //均存储在data段中,作用域在{}之内,生存期在整个main结束后才自动调用析构函数销毁。  
    6.         static Test t(100);   
    7.           
    8.         static Test t2;  
    9.     }  
    10. }  

             对于堆上的对象

            如下:

    [cpp] view plain copy
     
    1. int main()  
    2. {  
    3.     ...  
    4.     {  
    5.         Test *t3 = new Test(20); //堆上创建的对象,即使跳出作用域{}也不能自动调用析构函数来释放对象。可见作用域与生存期是不同的。作用域仅仅是对象的可见范围。  
    6.         delete *t3; //主动析构。  
    7.     }  
    8. }  

            总而言之,静态全局对象,全局对象,静态局部对象都存储在data段中,静态全局对象与全局对象先于main函数调用构造函数,但它们三个都在main结束后自动调用析构函数销毁对象。堆上对象创建于堆,离开作用域范围后依旧不会自动销毁,需要手动销毁对象。局部对象创建于栈上,离开作用域后自动销毁。只有全局的普通变量才区分.bss段与.data段,未被初始化的全局变量存放在.bss段中,初始化的全局变量存放在data段中,全局变量作用域在整个程序的生命周期。局部变量在栈上创建,作用域在局部。另外切记,作用域与生存期有时并不等同。


  • 相关阅读:
    WIN7 系统 右键计算机 点击管理 出现对话框:找不到文件。
    电脑优化的方法
    小问题总结
    sql server常用函数、常用语句
    java绝对路径和相对路径的理解
    日常开发常用网站(持续更新……)
    jquery字符串序列化方法总结
    J2EE保留小数问题
    error C2556: 'const char &MyString::operator [](int)' : overloaded function differs only by return type from 'char &MyString::operator [](int)'
    有个人愿意对你微笑,如果她的眼神是坚定的,她是谁对我其实已经不重要了
  • 原文地址:https://www.cnblogs.com/xiaouisme/p/9224750.html
Copyright © 2020-2023  润新知