static代表定义静态变量或方法,对于static的用法,我一共总结为两种,分别是在类中和在类外,根据变量和方法又分为四种,下面分这四种情况进行阐述。
-
在类中定义静态成员变量
对于类中的static成员变量,其存储地址在内存中只有一份,并且被每一个实例化的对象共享,如果static成员变量在其中一个实例化的对象中更改,则其他所有实例化的对象中static成员变量都更改。因为实际上share同一份内存。
作用:解决类中的变量不属于实例的问题。class A { public: static int a; }; int A::a = 0;//一定要在类外初始化,否则会出现未解析的外部命令报错 int main() { A a1, a2; cout << "这是类A的static int成员变量a的值:"<<A::a << endl; a1.a = 1; cout << "这是实例a2的static int成员变量a的值:" << a2.a << endl; return 0; //输出 0,1 }
-
在类中定义静态成员函数
对于类中的static成员函数,在内存中同样只存在一份,由类所有,所有实例共享。并且犹豫static成员函数没有this指针,无法调用非静态成员函数,也不能使用非静态成员变量。但可以调用静态成员函数。
并且,只有当static成员函数访问权限为public时,可以在类外调用。
对于类中的static成员,static使成员归类所有,所有实例共享成员,目的是使所有实例中该static成员能够统一。考虑一个银行利率的场景,对于所有的用户实例,利率应当相同,应当将利率定义为static成员,这就是static静态成员的作用。
静态成员函数可以访问类的函数而避免实例化,一般情况下,静态成员函数主要用来访问全局变量或同一个类中的静态数据成员,特别是和后者一起使用。
作用:解决访问类中的static成员变量的问题。(非static成员变量无法访问)class A { public: static int a; static void fun1() { cout << "这是static fun1()" << endl; fun2();//此处会报错,非静态成员引用必须与特定对象相对 //如果fun2()是静态函数,编译可以通过,运行结果正常 } void fun2() { cout << "这是non-static fun2()" << endl; } }; int A::a = 0; int main() { A a1, a2; a1.fun1(); return 0; }
-
在类外定义静态变量
static int a;
对于全局静态变量,static int a储存在全局区,作用域为全局。而对于局部静态变量,依然储存在全局区,但作用于为局部。
静态全局变量可以把静态变量的作用域限制在全局,并且只能在当前的.cpp文件中使用,防止变量被其他文件共享。
对于静态局部变量,它的作用域在该局部范围内。比如一个定义在函数体内的静态局部变量,对于非静态局部变量,函数体执行完毕后,该变量会被清理,内存被回收,但对于静态局部变量,当这个函数下一次被调用时,仍然从未清理的地方开始,这就是静态局部变量的“全局生存期”。
作用:解决多个相互有依赖关系的目标文件互相有符号污染的问题。 -
在类外定义静态函数
作用:解决一些变量只需要一个实例,且只需要初始化一次的问题。static void fun() { cout << "这是static void fun()" << endl; }
C++代码存放在代码区,而函数在运行时被放到栈区,其中静态函数被放到静态区。函数也在代码段。
最后插入一段完整static类/非类、静态全局/局部代码演绎
#include<iostream>
using namespace std;
class A {
private:
static int a;
int b;
static void fun() {
cout << a << endl;
cout << "这是static void fun()" << endl;
}
};
static void fun1() {
int a = 0;
cout << "这是非类中的static void fun1(),它的地址是:" <<&fun1<< endl;
}
void fun2(int c) {
if (c == 2) return;
int a = 0;
static int b = 0;
cout << "int a的地址是:" << &a << endl;//可以看到第一次的a的地址与第二次不同,而第一次的b的地址与第二次的相同
cout << "static int b的地址是:" << &b << endl;
cout << "这是非类中的void fun2(),它的地址是:" << &fun2 << endl;
fun2(c + 1);
}
int A::a = 0;
int main() {
//A::fun();
cout << "fun1()的地址是:" << &fun1 << endl;
cout << "fun2()的地址是:" << &fun2 << endl;
fun1();
fun2(0);
//fun2(1);
return 0;
}
最后总结变量的创建时间:
- 静态方法中的变量在调用时创建
- 静态局部、全局变量在编译时创建