转自: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. BeanUtils进行日期格式的拷贝转换

    自定义Converter的方法: import java.text.ParseException; import java.text.SimpleDateFormat; import org.apac ...

  2. Smali语法

    看阿里巴巴的<深入探索Android热修复>,里面的代码看不懂,一查才知道是Smali语法,百度了语法,转载如下 转载自smali 语言语法 1.smali apk文件通过apktool反 ...

  3. QMessageBox的用法

    QMessageBox的用法   先来看一下最熟悉的QMessageBox::information.我们在以前的代码中这样使用过:   QMessageBox::information(NULL,  ...

  4. 51nod 1277 字符串中的最大值

    题目链接 51nod 1277 字符串中的最大值 题解 对于单串,考虑多串的fail树,发现next数组的关系形成树形结构 建出next树,对于每一个前缀,他出现的次数就是他子树的大小 代码 #inc ...

  5. 洛谷.3065.第一!First!(Trie 拓扑)

    题目链接 \(Description\) 给出n个字符串,问重定义英文字符的顺序(即字典序),有哪些单词可能排在第一 \(Solution\) 一个单词想要排在第一,首先是没有其它字符串是它的前缀.那 ...

  6. yum 安装 jenkins

    环境:已安装 tomcat 安装(如果yum下载速度比较忙可以下载下来再安装) yum -y install https://pkg.jenkins.io/redhat/jenkins-2.77-1. ...

  7. 总结的U3D面试题

    1.配置Unity 3d调试环境? 1)          Visual Studio Tools for Unity 2)          访问http://unityvs.com 3)      ...

  8. v$instance如何生成

    参考:http://www.itpub.net/thread-1284858-1-1.html 1.ORACLE 先创建的x$ 表即RDBMS的内部表 2.然后在X$表的基础上创建了GV$ 视图.  ...

  9. Java基础之理解Annotation

    一.概念 Annontation是Java5开始引入的新特征.中文名称一般叫注解.它提供了一种安全的类似注释的机制,用来将任何的信息或元数据(metadata)与程序元素(类.方法.成员变量等)进行关 ...

  10. ASP.NET Web API中把分页信息放Header中返回给前端

    谈到ASP.NET Web API的分页,考虑的因素包括: 1.上一页和下一页的uri2.总数和总页数3.当前页和页容量 接着是服务端的数据以怎样的形式返回? 我们通常这样写: {    totalC ...