定义
static是C++中关于存储类型的说明符,用static说明的变量称为静态变量。它被用来控制变量的存储方式和可见性。
什么情况下使用静态变量
在函数内部定义的变量,当程序执行到它的定义处时,编译器为它在栈上分配空间,函数在栈上分配的空间在此函数执行结束时会释放掉,这样就产生了一个问题: 如果想将函数中此变量的值保存至下一次调用时,如何实现? 最容易想到的方法是定义为全局的变量,但定义一个全局变量有许多缺点,最明显的缺点是破坏了此变量的访问范围(使得在此函数中定义的变量,不仅仅只受此函数控制)。static关键字则可以很好的解决这个问题。
另外,在 C++ 中,需要一个数据对象为整个类而非某个对象服务,同时又力求不破坏类的封装性,即要求此成员隐藏在类的内部,对外不可见时,可将其定义为静态数据。
静态变量的特点
- 静态变量军存储在全局数据区,如果程序未显示地给出初始化值,则等效初始化为全0.
- 静态变量占有的空间要到整个程序执行结束时才释放,因此静态变量具有全局生命期。
- 静态类成员是由static修饰的类成员,为其所有对象共享,不管有多少对象,静态成员只有一个存在于公共内存中
几种使用方式
全局静态变量
全局可访问,在内存中只有一份拷贝,可被很多函数修改。1
2
3
4
5
6
7
8
9
10
11
12
13
static int i = 1; //作用域是整个file
void get(){
std::cout << "in func , the i is " << i << std::endl;
}
int main(){
std::cout << "the i is " << i << std::endl;
get();
return 0;
}
局部静态变量
只能在这个函数中才能被调用。
函数调用结束后,一般局部变量都被回收了,静态变量还存在1
2
3
4
5
6
7
8
9
10
11
12
13
14
void get(){
static int i = 1;
std::cout << "the i is " << i << std::endl;
i++;
}
int main(){
get(); // i = 1
get(); // i = 2
//std::cout << "the i is " << i << std::endl; // 这种是错误的
return 0;
}
全局静态函数
其实跟一般的函数差不多,但是它将该函数的链接属性限制为内链接,只能在本编译单元中使用(也就是本文件),不能被extern等在外部文件中引用。
1 | static void get(){ |
静态数据成员
格式: 类名::静态数据成员名
需要注意,给静态数据成员初始化必须在类外面。
原理跟函数中的静态变量类似,类实例化出来的对象被销毁后,类变量(静态成员变量)还是存在在内存中的。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class Widget{
public:
Widget(int i){
a = i;
}
void get();
private:
static int a; // 声明静态变量
};
int Widget::a = 1; // 由于是类变量不是属于专属于一个对象的,被所有对象共享
// 所以需要在类外定义
void Widget::get(){
std::cout << "the a is " << a++ << std::endl;
}
int main(){
Widget w(1);
w.get(); // a = 1
w.get(); // a = 2
return 0;
}
静态函数成员
1 |
|
参考: