C++中的static的作用
C++中的关键字static,顾名思义表示静止,静态,下面是C++中static的一些常见应用
一,作用于函数内部的局部变量
局部作用域静态变量的特点:当一个函数返回后,下一次再调用时,该变量还会保持上一回的值,函数内部的静态变量只开辟一次空间,且不会因为多次调用产生副本,也不会因为函数返回而失效
例如:
如果我想实现fun()函数功能:在函数内部定义count计数器,打印出每次调用它的次数,你可能会这样写,如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| #include<iostream> using namespace std; void fun() {
int count = 0; count++; cout << "count=" << count << endl; } int main() { cout << "Calling the “fun()”for the first time! " << endl; fun(); cout << "Calling the “fun()”for the second time! " << endl; fun();
return 0; }
|
我们预计结果为:
第一次调用,打印出结果 1
第二次调用,打印出结果 2
我们试着运行后,结果并不是我们想要的,如下图:

两次运行结果都是1,这是为什么呢,原来是每次调用函数结束后,count值会失效,当再次调用函数时,count值会重新生成,初始值为1,这就达不到我们想要的结果,那该怎么办呢?这时候就需要static关键字作用的静态变量,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| #include<iostream> using namespace std; void fun() { static int count = 0; count++; cout << "count=" << count << endl; } int main() { cout << "calling the “fun()”for the first time! " << endl; fun(); cout << "calling the “fun()”for the second time! " << endl; fun(); return 0; }
|
运行结果跟我们想要的结果就一致啦

另外,普通局部变量如果未赋予初值,编译器会报错

报错如下:

当局部变量加上static 后,定义时未赋予初值时,会默认初始化0

二,作用于类的成员,解决同一个类的不同对象之间数据和函数共享问题
1,作用于类的数据成员,使其成为静态数据成员
静态成员在每一个类中只有一个副本,由该类所有对象共同维护和使用,从而实现同一个类的不同对象数据共享。需要注意的是,如下
访问静态数据成员方式:类名::标识符
对静态数据成员初始化:在类定义外进行
之所以进行类名::标识符进行访问,是因为静态数据成语哪不属于任何一个对象,而在类外进行定义是因为需要以这种方式专门为他们分配空间。
举例说明:
直接在类内定义静态数据成员,编译器会报错

错误如下:

正确做法:

下面通过一段代码,理解一下对于“同一个类的不同对象数据共享”的理解,代码如下:
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 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| #include <iostream> using namespace std;
class Point { public: Point(int x = 0, int y = 0) : x(x), y(y) { count++; } Point(Point &p) { x = p.x; y = p.y; count++; } Point() { count--; } int getX() { return x; } int getY() { return y; }
void showCount() { cout << " Object count = " << count << endl; } private: int x, y; static int count; };
int Point::count = 0;
int main() { Point a(4, 5); cout << "Point A: " << a.getX() << ", " << a.getY(); a.showCount();
Point b(a); cout << "Point B: " << b.getX() << ", " << b.getY(); b.showCount();
cout << "Point A: " << a.getX() << ", " << a.getY(); a.showCount();
return 0; }
|
输出结果:

这里的Point类里面的A,B对象共有的属性object count 都是2 。该运行结果清晰的显示了同一个类的不同对象数据共享的理解。
2,作用于类的函数成员,使其成为静态函数成员
静态成员函数就是使用static关键字声明的函数成员,同静态数据成员一样,静态成员函数也属于整个类,由该类所有对象共同拥有,为所有对象共享
(1)静态成员函数主要用于处理该类的静态数据成员,可以直接调用静态数据成员。如果访问非静态成员,要通过对象来访问。例子如下:**
**
1 2 3 4 5 6 7 8 9 10 11 12 13
| class A { public: static void f(A a); private: int x; static int y; }; void A::f(A a) { cout << x; cout << a.x; cout << y; }
|
上面代码中报错如下:

所以,静态成员函数访问非静态成员,一定要通过对象来访问
(2)如果想在类外调用静态成员函数呢?——类外代码一般使用类名和作用域操作符来调用静态成员函数。
访问方式:一般通过类名::函数名调用,也可用类.函数名调用
举例说明,如下:

三,总结:
当static作用于非类内函数的局部变量时,每次函数调用不会随着函数返回而失效,当static作用于类内成员时,由该类所有对象共同维护和使用,从而实现同一个类的不同对象数据共享。