C++中static关键字

1.static

控制变量的存储方式和可见性。

2.为什么要引入static?

函数内部定义的变量,在程序执行到它的定义处时,编译器为它在栈上分配空间,但函数在栈上分配的空间在此函数执行结束时会释放掉,这样就产生了一个问题:如果将函数中此变量的值保存至下一次调用时,如何实现?最容易想到的方法是定义一个全局的变量,但定义为一个全局变量有很多缺点,最明显的缺点是破坏了此变量的访问范围(使得在此函数中定义的变量,不仅仅受此函数控制)。

3.什么时候用static?

需要一个数据对象为整个类而非某个对象服务,同时又力求不破坏类的封装性,即要求此成员隐藏在类的内部,对外不可见。

4.static的内部机制:

静态数据成员要在程序一开始运行时就必须存在。因为函数在程序运行中被调用,所以静态数据成员不能在任何函数内分配空间和初始化

这样,它的空间分配有三个可能的地方,一是作为类的外部接口的头文件,那里有类声明;二是类定义的内部实现,那里有类的成员函数定义;三是应用程序的main()函数前的全局数据声明和定义处。

静态数据成员要实际地分配空间,故不能在类的声明中定义(只能声明数据成员)。类声明只声明一个类的“尺寸和规格”,并不进行实际的内存分配,所以在类声明中写成定义是错误的。它也不能在头文件中类声明的外部定义,因为那会造成在多个使用该类的源文件中,对其重复定义。

static被引入以告知编译器,将变量存储在程序的静态存储区而非栈上空间。

5.static的优势

可以节省内存,因为它是所有对象所公有的,因此,对多个对象来说,静态数据成员只存储一处,供所有对象共用。静态数据成员的值对每个对象都是一样,但它的值是可以更新的。只要对静态数据成员的值更新一次,保证所有对象存取更新后的相同的值,这样可以提高实践效率。

6.引用静态数据成员

声明:加上static关键字

引用格式:<类名>::<静态成员名>

7.注意事项

①类的静态成员函数是属于某个类而非类的对象,所以它没有this指针,这就导致了它仅能访问类的静态数据和静态成员函数

②静态数据成员是静态存储的,所以必须对它进行初始化

③初始化在类体外进行,而前面不加static,以免与一般静态变量或对象相混淆;不用加访问权限控制符private、public等;例:<数据类型><类名>::<静态数据成员名>=<值>

④静态成员函数和静态数据成员一样,它们都属于类的静态成员,它们都不是对象成员。因此,对静态成员的引用不需要用对象名

例1:

class Point
{
public:
	void output()
	{
		cout<<"output()"<<endl;
	};
	static void init()
	{
		cout<<"init()"<<endl;
	};
};//勿忘记类定义最后的“;”。

void main()
{
	Point pt;
	pt.init();
	pt.output();
}
编译正确。
例2:

void main()
{
	Point::output();
}
类定义相同,main()改为上述,则编译错误。提示:非静态成员引用必须与特定对象相对。未实例化一个类的具体对象时,类是没有被分配内存空间的。
改为如下,编译通过。

void main()
{
	Point::init();
}
因为在类的定义时,它静态数据和成员函数就有了它的内存区,它不属于类的任何一个具体对象。
例3:

class Point
{
public:
	void output()
	{
		cout<<"output()"<<endl;
	};
	static void init()
	{
		x = 0;
		y = 0;
		cout<<"init()"<<endl;
	};
private:
	int x;
	int y;
};//勿忘记类定义最后的“;”。

void main()
{
	Point::init();
}
error:提示对非静态成员的非法引用。即:在一个静态成员函数里错误的引用了数据成员,还是那个问题,静态成员(函数)不属于任何一个具体的对象,那么在类的具体对象声明之前就已经有了内存区,而现在非静态数据成员还没有分配内存空间,那么这里调用就错误了,就好像没有声明一个变量却提前使用他一样。

例4:

class Point
{
public:
	void output()
	{
		cout<<"output()"<<endl;
	};
	static void init()
	{
		x = 0;
		y = 0;
		cout<<"init()"<<endl;
	};
private:
	static int x;
	static int y;
};//勿忘记类定义最后的“;”。

void main()
{
	Point::init();
}
结果如下:

因为静态的成员变量要进行初始化。

例5:

class Point
{
public:
	void output()
	{
		cout<<"output()"<<endl;
	};
	static void init()
	{
		x = 0;
		y = 0;
		cout<<"init()"<<endl;
	};
private:
	static int x;
	static int y;
};//勿忘记类定义最后的“;”。

int Point::x = 0;
int Point::y = 0;

void main()
{
	Point::init();
}
成功生成。在main()方法上面为静态成员初始化。


参考:

http://blog.csdn.net/cn_cainiao/article/details/5943070


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值