static可以用于修饰普通的变量和函数,也可以用于修饰类的成员
- 普通应用
1.修饰普通变量
修饰全局变量:将变量的作用域限制在所属文件
修饰局部变量:将变量的生存周期延迟到程序结束
2.修饰普通函数
将函数的作用域限制在所属文件
- 在类中应用
被static修饰的类的成员被类的所有对象共享,不属于某个具体对象,普通的类的成员都有this指针指向本对象,而static修饰的成员不属于特定对象因此没有this指针。
1.修饰类的数据成员
在类中声明,在类外定义。定义方式 <类名::变量名=值 >这样做是有原因的,因为静态成员属于整个类,而不属于某个对象,如果在类内初始化,会导致每个对象都包含该静态成员,这是矛盾的。
特例:当被static修饰的数据成员具有const关键字时需要在类中初始化,但仍需在类外定义
2.修饰数据成员
因为static成员函数不具有this指针,所以不能访问非静态成员。
static 成员函数访问方式
- (.)和(->)
- <类名>::<静态成员函数名>(<参数表>)
其他:
- 未经初始化的静态全局变量会被程序自动初始化为0
- static变量只在第一调用时初始化一次,之后不再初始化(只能赋值)
1 int SetValue(int a) 2 { 3 static int v=a; //执行一次,初始化为a 4 return v; 5 } 6 int main() 7 { 8 cout << SetValue(1) << " " << SetValue(2)<<endl; 9 }
结果:
static int v=a;只初始化一次,这一步只有在第一次调用的时候执行
对应的:
1 int SetValue(int a) 2 { 3 static int v; //执行一次,初始化为0 4 v= a; //赋值操作 5 return v; 6 } 7 int main() 8 { 9 cout << SetValue(1) << " " << SetValue(2)<<endl; 10 }
结果:
- 函数内部声明的static变量,可作为对象间的一种通信机制,局部变量被声明为static,那么将只有唯一的一个静态分配的对象,它被用于在该函数的所有调用中表示这个变量。这个对象将只在执行线程第一次到达它的定义时初始化。
1 const int& SetValue(int a) 2 { 3 static int v; 4 v=a; 5 return v; 6 } 7 int main() 8 { 9 cout << SetValue(1) << " " << SetValue(2)<<endl; 10 if (SetValue(1) == SetValue(2)) 11 cout << "yes" << endl; 12 else 13 cout << "no" << endl; 14 }
结果:
由结果可知SetValue(1)和SetValue(2)确实都改变了v的值,但第十行却出现了SetValue(1)==SetValue(2),这是因为返回值是reference,都是指向SetValue内部的static v,也就是说调用端看到的都是static v的“现值”。
对应的:
1 const int& SetValue(int a) 2 { 3 static int v; 4 v=a; 5 return v; 6 } 7 int main() 8 { 9 cout << SetValue(1) << " " << SetValue(2)<<endl; 10 int a = SetValue(1); 11 int b = SetValue(2); 12 if (a == b) 13 cout << "yes" << endl; 14 else 15 cout << "no" << endl;
结果:
- 保持变量内容的持久,位于函数内的静态局部变量会在下一次调用之前保持上一次调用后的值。