static关键字

local static变量

如果一局部变量被声明为static,那么将只有唯一的一个静态分配的对象,它被用于在该函数的所有调用中表示这个变量。这个对象将只在执行线程第一次到达它的定义使初始化。 构造函数是在控制线程第一次通过该对象的定义时调用。在程序结束时,局部静态对象的析构函数将按照他们被构造的相反顺序逐一调用,没有规定确切时间。

  • 有唯一副本, 存放在内存的静态存储区域

  • 只在函数作用域内可见

  • 可以用来设计单例模式的对象

    通常,在函数体内定义了一个变量,每当程序运行到该语句时都会给该局部变量分配栈内存。但随着程序退出函数体,系统就会收回栈内存,局部变量也相应失效。但是有时候我们需要在两次调用之间对变量的值进行保存。通常的想法是定义一个全局变量来实现。但这样一来,变量已经不再属于函数本身了,不再仅受函数的控制,给程序的维护带来不便。  静态局部变量正好可以解决这个问题。静态局部变量保存在全局数据区,而不是保存在栈中,下次调用时值还是上次的调用结束的值。

global static变量

  • 静态全局变量只在所在文件可见,非静态的全局变量在各个源文件中都是有效的
  • 其它文件中可以定义相同名字的变量,不会发生冲突
  • 全局数据区( 静态存储区域)分配内存
代码区
全局数据区
堆区
栈区

对局部静态变量对比

  • 局部变量改为静态变量后,改变了它的存储方式,即改变了它的生存期
  • 全局变量改为静态变量后,改变了它的作用域, 限制了它的使用范围

静态成员变量和静态成员函数

如果一个变量是类的一部分,但却不是该类的各个对象的一部分,它就被成为是一个static静态成员。

  • 一个static成员只有唯一的一份副本,而不像常规的非static成员那样在每个对象里各有一份副本
  • 访问类静态成员,不需要通过特定对象去调用的函数
  • 类的静态成员函数只能访问类的静态成员(变量或函数)

静态对象

对于C语言的全局和静态变量,不管是否被初始化,其内存空间都是全局的;如果初始化,那么初始化发生在任何代码执行之前,属于编译期初始化。由于内置变量无须资源释放操作,仅需要回收内存空间,因此程序结束后全局内存空间被一起回收,不存在变量依赖问题,没有任何代码会再被执行!

C++引入了对象,这给全局变量的管理带领新的麻烦。C++的对象必须有构造函数生成,并最终执行析构操作。由于构造和析构并非分配内存那么简单,可以说相当复杂,因此何时执行全局或静态对象(C++)的构造和析构呢?这需要执行相关代码,无法在编译期完成,因此C++标准规定:全局或静态对象当且仅当对象首次用到时才进行构造,并通过atexit()来管理对象的生命期,在程序结束之后(如调用exit,main),按FILO顺序调用相应的析构操作!

简而言之,C++未规定不同编译单元静态对象的初始化次序(Effective C++,条款04对这个问题进行了讨论),全局或静态对象当且仅当对象首次用到时才进行构造。

扩展

​ 术语static有着不寻常的历史。起初,在C中引入关键字static是为了表示退出一个块后仍然存在的局部变量。随后,static在C中有了第二种含义:用来表示不能被其它文件访问的全局变量和函数。为了避免引入新的关键字,所以仍使用static关键字来表示这第二种含义。最后,C++重用了这个关键字,并赋予它与前面不同的第三种含义:表示属于一个类而不是属于此类的任何特定对象的变量和函数(与Java中此关键字的含义相同)。

------ 本文结束------
赞赏此文?求鼓励,求支持!
  • 本文标题: static关键字
  • 本文作者: Jiang.G.F
  • 创建于: 2019年12月21日 - 22时12分
  • 更新于: 2020年03月03日 - 11时03分
  • 本文链接: https://gfjiangly.github.io/C++/static.html
  • 版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!
0%