static 关键字用于修改变量的存储方式和可见性。
在函数内部定义的局部变量,当执行到函数定义处时,编译器为它在栈空间分配存储空间,函数执行完毕释放该空间。那么,如果想保存函数中此变量的值至下一次调用时,如何实现?最简单粗暴的方法就是定义一个全局变量,但全局变量破坏了变量的范围:所有的函数均可修改该变量。static关键字可以很好地解决该类问题。
此外,需要一个数据对象为某个类而非某个具体的变量服务,即要求此成员在类的内部,对外不可见时,可将其定义为静态数据。
静态数据的存储
…
类中静态成员变量的使用
#include <iostream>
#include <vector>
using namespace std;
class Test
{
public:
/**
使用静态变量实现同一类的多个对象共享数据的目的。 static 成员变量属于类,不属于某个具体的对象,
即使创建多个对象,也只为cout分配一份内存,所有对象使用的都是这份内存中的数据。当某个对象修改了 cout,也会影响到其他对象。
*/
static int count;
};
// 静态成员变量在初始化时不能再加static,但必须有数据类型。
// 静态成员变量的内存既不是在类声明的时候分配也不是在创建对象时分配,而是在类外初始化时分配,即没有在类外初始化的的静态成员变量不能使用。
int Test::count=9; /*static类对象必须在类外进行初始化:static修饰的变量先于对象存在,所以static修饰的变量要在类外进行初始化*/
/*static修饰的成员变量在对象中是不占用内存的,因为它不是跟对象一起在堆或者栈中生成的,它是在静态存储区生成的*/
/*初始化时可以赋初值,也可以不赋值。如果不赋值,那么会被默认初始化为 0。
全局数据区的变量都有默认的初始值 0,而动态数据区(堆区、栈区)变量的默认值是不确定的,一般认为是垃圾值。
*/
int main()
{
Test t1;
cout << t1.count << endl;
Test t2;
t1.count = 100; /*static修饰的类变量是所有对象共享的,只要有一个对象改变了static静态变量,整个对象的都会变*/
cout << t2.count << endl;
cout<< t1.count <<endl; // 被对象t2修改后,所有对象都被修改了
/*static 成员变量不占用对象的内存,而是在所有对象之外开辟内存,既可以通过对象来访问,也可以不创建对象通过类来访问。
具体来说,static 成员变量和普通的 static 变量类似,都在内存分区中的全局数据区分配内存*/
cout<< Test::count<<endl;
Test *ts = new Test;
cout<<ts->count<<endl;
}
全局变量与全局静态变量的区别
- 全局变量默认具有外部链接性的,其作用域为整个工程,在一个文件中定义的全局变量在另一个文件中通过extern全局变量的声明就可以使用全局变量;
- 全局静态变量是显式用 static 修饰的全局变量,作用域为本文件,外部文件通过extern声明也不能使用;
总结
- static修饰的局部变量只执行一次初始化,而且延长了局部变量的生命周期,直到程序运行结束才释放。
- static修饰的全局变量,该变量只能在本文件中使用,即便是extern外部声明也不可以。
- static修饰的函数,该函数只能在本文件中调用,不能被其他文件调用。