c++中static的用法
1、静态全局变量
全局变量的空间会在程序的生命周期内分配,在全局变量的前面加上static,变成静态全局变量。
#include <iostream> #include <string.h> using namespace std; static int n = 5; int main() { n = 10; printf("%d\n", n); return 0; }
静态全局变量在全局数据区分配内存,那它和全局变量有啥区别呢?
全局变量不但在本文件中可以被访问,在其他文件中同样可以访问。写代码时很容易在不同文件定义相同名字的全局变量,这就会引发冲突。
而静态全局变量只能在声明它的整个文件可见,限制了该变量的访问范围。
同样的,静态全局函数,在全局函数前加上static,表示只能在声明文件中被访问。
2、静态局部变量
局部变量也就是定义在函数内部的变量,函数局部变量存放在栈区,该变量的生命周期由所在 {} 决定,进入 {} 作用范围而分配内存空间,退出 {} 作用范围而释放内存空间。
在局部变量的前面加上static,变成静态局部变量,即使多次调用该函数,静态变量的空间也只分配一次。
#include <iostream> #include <string.h> using namespace std; void fun() { static int n = 5; printf("%d\n", n); n++; } int main() { int i; for(i=0; i<5; i++) { fun(); } return 0; }
前一次调用的变量值通过下一次函数调用传递,可以存储之前的函数状态。
3、静态成员变量
我们知道,一个类可以定义多个对象,每个对象都会对类中的普通成员变量进行空间分配,这些变量只由它所在对象使用。
静态成员变量是该类的所有对象所共有的。对于普通成员变量,每个类对象都有自己的一份拷贝,而静态成员变量整个类就一份,静态成员变量只分配一次内存,类的所有对象都共享这个变量,不属于任何一个类,不需要对象就可以访问。
静态成员变量不属于特定的对象,不会占用对象的内存,必须在类的外面进行初始化。对象的内存中只包括普通成员变量,注意不包括任何成员函数。sizeof(类名) 不会计算静态成员变量和成员函数。
普通成员变量随这对象的产生而产生,静态成员变量随着类的产生而产生,所以静态成员变量不能由构造函数初始化,即使没有对象,也可以访问静态全局变量。
#include <iostream> #include <string.h> using namespace std; class A { public: static int n; //声明静态成员变量 }; int A::n = 5; //定义并初始化静态成员变量 int main() { printf("n:%d, sizeof(A):%d\n", A::n, sizeof(A)); return 0; }
4、静态成员函数
就像类中的静态成员变量一样,静态成员函数也不依赖于类的对象,不具体作用于某个对象。
普通成员函数参数自带一个this指针,this指针指向类的对象本身,因为普通成员函数总是属于类对象,当函数被调用时,系统会把当前对象的起始地址赋给 this 指针。
静态成员函数属于类本身,因此不具有this指针。它无法访问属于类对象的非静态成员变量和非静态成员函数,它只能访问其他静态成员变量和静态成员函数。
可以通过对象来调用,但还是建议使 类名::静态成员函数 调用静态成员函数。
静态成员函数和静态成员变量在类实例化之前就已经存在可以访问,而此时非静态成员还是不存在的,因此静态成员函数不能访问非静态成员变量。
#include <iostream> #include <string.h> using namespace std; class A { private: static int n; //声明静态成员变量 public: static void fun(); int m; }; int A::n = 5; //定义并初始化静态成员变量 //定义静态成员函数,不能加static void A::fun() { printf("n:%d\n", n); // printf("m:%d\n", m); //error } int main() { A aa; aa.fun(); A::fun(); return 0; }