引入
函数内部定义的变量,当程序执行到它的定义处时,编译器为它在栈上分配空间,函数执行结束时会释放掉他的内存。为保持变量的持久性,我们可以声明其为全局变量、全局函数。但全局函数又破坏了变量的访问范围,为了控制变量的存储方式和可见性,引入static
关键字。
作用
- 修饰局部变量 — 延长生命周期
局部变量一般创建在栈区,将其声明为static
会导致变量创建在全局区。全局区的变量只会在程序运行前初始化一次,其生命周期会一直延续到整个程序执行结束。
生命周期以及存储空间发生了变化,但其作用域并没变。
- 修饰全局变量、函数 — 信息隐藏,对其他文件不可见。
当同时编译多个文件时,所有未加 static 前缀的全局变量和函数都具有全局可见性。(可被其他文件访问)
声明为static
后,该变量/函数仅在该文件中可见,不能被其他文件访问。
同一工程下,不能被其他文件引用;文件外可定义同名变量/函数。
- 修饰类成员
被static
修饰的类成员函数、类成员变量,统一属于类的静态资源,是类实例之间共享的,不是属于此类的任何特定对象。
静态非常量数据成员在类内仅声明,只能在类外定义和初始化。
static
函数不接受this
指针只能访问类的 static
成员变量。(因为不属于某个具体对象)
static 成员函数不能被 virtual 修饰(同样,因为不属于具体的某个对象)
虚函数的重写是通过每个对象内的虚指针去调用,而虚指针调用需要用到this
。(this
指针 -->vptr
-->vtable
-->virtual function
)
静态成员函数中不能引用非静态成员。类的非静态成员函数可以调用用静态成员函数。
静态的资源属于类,并没有实例化对象,没办法知道该类具体有哪些非静态的资源。而对象创建时,类有哪些成员是已知的,均可访问。
初始化
初始化只有一次,但是可以多次赋值,在主程序之前,编译器已经为其分配好了内存。
在静态数据区,内存中所有的字节默认值都是
0x00
,可以不用人为的初始化。
在 C++中,初始化时在执行相关代码时才会进行初始化,主要是由于 C++引入对象后,要进行初始化必须执行相应构造函数和析构函数,在构造函数或析构函数中经常会需要进行某些程序中需要进行的特定操作,并非简单地分配内存。