C++中的static的作用
C++中的关键字static,顾名思义表示静止,静态,下面是C++中static的一些常见应用
一,作用于函数内部的局部变量
局部作用域静态变量的特点:当一个函数返回后,下一次再调用时,该变量还会保持上一回的值,函数内部的静态变量只开辟一次空间,且不会因为多次调用产生副本,也不会因为函数返回而失效
例如:
如果我想实现fun()函数功能:在函数内部定义count计数器,打印出每次调用它的次数,你可能会这样写,如下
#include<iostream>
using namespace std;
void fun()
{
int count = 0;//不加关键字static
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关键字作用的静态变量,如下:
#include<iostream>
using namespace std;
void fun()
{
static int count = 0;//static 作用的静态变量
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,作用于类的数据成员,使其成为静态数据成员
静态成员在每一个类中只有一个副本,由该类所有对象共同维护和使用,从而实现同一个类的不同对象数据共享。需要注意的是,如下
访问静态数据成员方式:类名::标识符
对静态数据成员初始化:在类定义外进行
之所以进行类名::标识符进行访问,是因为静态数据成语哪不属于任何一个对象,而在类外进行定义是因为需要以这种方式专门为他们分配空间。
举例说明:
直接在类内定义静态数据成员,编译器会报错
错误如下:
正确做法:
下面通过一段代码,理解一下对于“同一个类的不同对象数据共享”的理解,代码如下:
#include <iostream>
using namespace std;
class Point { //Point类定义
public: //外部接口
Point(int x = 0, int y = 0) : x(x), y(y) { //构造函数
//在构造函数中对count累加,所有对象共同维护同一个count
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); //定义对象a,其构造函数回使count增1
cout << "Point A: " << a.getX() << ", " << a.getY();
a.showCount(); //输出对象个数
Point b(a); //定义对象b,其构造函数回使count增1
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)静态成员函数主要用于处理该类的静态数据成员,可以直接调用静态数据成员。如果访问非静态成员,要通过对象来访问。例子如下:**
**
class A {
public:
static void f(A a);
private:
int x;
static int y;
};
void A::f(A a)
{
cout << x;//对x的引用是错误的
cout << a.x;//正确
cout << y;//对x的引用是正确的的,引用静态数据成员
}
上面代码中报错如下:
所以,静态成员函数访问非静态成员,一定要通过对象来访问
(2)如果想在类外调用静态成员函数呢?------类外代码一般使用类名和作用域操作符来调用静态成员函数。
访问方式:一般通过类名::函数名调用,也可用类.函数名调用
举例说明,如下:
三,总结:
当static作用于非类内函数的局部变量时,每次函数调用不会随着函数返回而失效,当static作用于类内成员时,由该类所有对象共同维护和使用,从而实现同一个类的不同对象数据共享。