C++中的static的作用

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作用于类内成员时,由该类所有对象共同维护和使用,从而实现同一个类的不同对象数据共享。

posted @ 2019-09-28 17:07  --believe  阅读(8468)  评论(0编辑  收藏  举报