转自: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段中

对于静态局部变量

如下所示:

  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函数结束后自动调用析构函数销毁

对于局部对象

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

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

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

对于静态局部对象

如下:

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

对于堆上的对象

如下:

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

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


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

  1. C语言内存分布之数据段

    不管我们以后是自己写代码还是读别人的代码,都应该想想这个变量默认存储的位置.在我们以后的嵌入式开发中,技巧性的代码越来越多的时候,我们可能把某一些代码放在一段.我们可以通过修改变量或者代码默认放置的段 ...

  2. linux代码段,数据段,BSS段, 堆,栈(二)

    //main.cpp int a = 0; 全局初始化区  char *p1; 全局未初始化区 main() { int b; 栈 char s[] = "abc"; 栈 char ...

  3. linux进程的堆栈空间_代码段(指令,只读)、数据段(静态变量,全局变量)、堆栈段(局部变量)、栈【转】

    转自:http://blog.csdn.net/gongweijiao/article/details/8207333 原文参见:http://blog.163.com/xychenbaihu@yea ...

  4. C语言全局未初始化数据段分析

    前言: 在分析C语言全局未初始化变量时,发现在目标文件中全局未初始化变量并不是直接放在bss段中. 再后来发现在两个.c文件中定义同名的全局变量,链接时居然没有发生符号重定义错误.才知道C语言弱定义的 ...

  5. 【转】linux代码段,数据段,BSS段, 堆,栈

    转载自 http://blog.csdn.net/wudebao5220150/article/details/12947445  linux代码段,数据段,BSS段, 堆,栈 网上摘抄了一些,自己组 ...

  6. 数据段、代码段、堆栈段、BSS段

    在linux中,进程在内存中一般会分为5个段,用来存放从磁盘载入的程序代码,等. 这五个段分别是: BSS段: 通常用来存放程序中未初始化的全局变量的一块内存区域.属于静态内存分配. 问题:全局变量不 ...

  7. 浅谈c语言代码段 数据段 bss段

    代码段.数据段.bss段 (1)编译器在编译程序的时候,将程序中的所有的元素分成了一些组成部分,各部分构成一个段,所以说段是可执行程序的组成部分. (2)代码段:代码段就是程序中的可执行部分,直观理解 ...

  8. 五个数据段之代码段、数据段、BSS、栈、堆

    继上文讲完了对内存管理的一些知识,下面笔者再对上篇文章的内容加以拓展,那么我们今天就来说一说5个数据段 五个数据段 进程(执行的程序)会占用一定数量的内存,它或是用来存放磁盘载入的程序代码,或是存放取 ...

  9. Unix代码段和数据段

    关于UNIX系统代码段和数据段分开的目的:方便编程. 1)代码段:代码段是用来存放可执行文件的操作指令,也就是说是它是可执行程序在内存中的镜像.代码段需要防止在运行时被非法修改,所以只准许读取操作,而 ...

随机推荐

  1. jstl标签比较格式化后的时间

    c:set 里面不支持任何标签,这样写不好讲格式化的值放到bdateVar里面 <c:set var="bdateVar" value="<fmt:forma ...

  2. AngularJS获取项目中定义的json文件

    项目结构: 文件夹js位于根路径下 $http.get('js/app/contact/contacts.json').then(function (res) { /*下面就是获取到的数据*/ $sc ...

  3. 算法竞赛入门经典-训练指南(10881-Piotr's Ants)

    题目大意: 一根长度为L的木棍一堆蚂蚁爬,向左或向右,速度都为1,若两蚂蚁碰撞则同时转头(转身时间忽略不计),问T时间之后每只蚂蚁的位置: 输入:t,(t个样例),每个样例输入 L,T,n,接下来是n ...

  4. HDU1575-Tr 【矩阵快速幂】(模板题)

    <题目链接> 题目大意: A为一个方阵,则Tr A表示A的迹(就是主对角线上各项的和),现要求Tr(A^k)%9973.  Input 数据的第一行是一个T,表示有T组数据. 每组数据的第 ...

  5. hdu 2546 饭卡【01背包】

    题目链接:https://vjudge.net/contest/103424#problem/C 饭卡                                Time Limit: 5000/ ...

  6. 009.Docker Compose部署及基础使用

    一 Docker Compose概述 Compose是一个用于定义和运行多容器Docker应用程序的工具.使用Compose,您可以使用YAML文件来配置应用程序的服务.然后,使用单个命令,您可以从配 ...

  7. 基本功 | Litho的使用及原理剖析

    1. 什么是Litho? Litho是Facebook推出的一套高效构建Android UI的声明式框架,主要目的是提升RecyclerView复杂列表的滑动性能和降低内存占用.下面是Litho官网的 ...

  8. sublime使用技巧之添加到右键菜单、集成VI

    熟悉开发工具,减少多余的操作流程有助于提高开发效率,而Sublime Text 2是sublime产品的经典版本,因此本文基于Sublime Text 2讲解sublime的使用技巧. VI的主要作用 ...

  9. CF 633 F. The Chocolate Spree 树形dp

    题目链接 CF 633 F. The Chocolate Spree 题解 维护子数答案 子数直径 子数最远点 单子数最长直径 (最长的 最远点+一条链) 讨论转移 代码 #include<ve ...

  10. Codeforces Round #514 (Div. 2)

    目录 Codeforces 1059 A.Cashier B.Forgery C.Sequence Transformation D.Nature Reserve(二分) E.Split the Tr ...