C++中static关键字在类中常见问题分析

一.static变量的初始化问题

static变量是和类绑定的变量,和一般变量和对象绑定不同。它在类实例化(创建对象)之前就分配空间,而非static变量是在创建对象时进行空间分配。那么该在哪里对static变量进行初始化呢?

1.能否在构造函数里进行static变量的初始化?
由前面的叙述可知,static变量在对象创建前就要进行空间分配。而构造函数是在创建对象时进行的调用。因此,不能在构造函数中对static变量进行初始化。
有如下代码:
#include "iostream"
using namespace std;
class test{
	public:
		static int a;
		test(){
			a=10;
			cout<<"a is "<<a<<endl;
		}
};
int main(void){
	test a;
}
用g++进行编译,显示:

test.cpp:(.text._ZN4testC2Ev[_ZN4testC5Ev]+0xf):对‘test::a’未定义的引用

test.cpp:(.text._ZN4testC2Ev[_ZN4testC5Ev]+0x19):对‘test::a’未定义的引用

collect2: error: ld returned 1 exit status


2.能否在类中对static变量初始化?

有如下代码:

#include "iostream"
using namespace std;
class test{
	public:
		static int a;
		test():a(10){
			cout<<"a is "<<a<<endl;
		}
};
int main(void){
	test a;
}

用g++进行编译,显示:

error: ISO C++ forbids in-class initialization of non-const static member ‘test::a’

C++标准中禁止对非const的static变量进行类内初始化。

也就是说如果将类中的

static int a;

改为:
const static int a;
便可以正常进行编译链接。

3.正确的初始化方式
#include "iostream"
using namespace std;
class test{
	public:
		static int a;
		test(){
			cout<<"a is "<<a<<endl;
		}
};
int test::a=10;
int main(void){
	test a;
}
类中的静态变量应该在类外进行初始化。

二.static成员与非static成员之间的调用

1.对static函数与非static函数的调用方式

1)通过类名的调用:因为static函数是与类绑定的,不依赖于对象,可以通过(类名::函数名)的方式来调用static函数。而非static函数则不能这样调用。
2)通过对象的调用:static函数和非static函数都可以通过(对象.函数名)的方式来调用。

2.static函数对类中其它成员变量的调用

有如下代码:
#include "iostream"
using namespace std;
class test{
	public:
		static int a;
		int b;
		test():b(10){}
		static void s_display(){
			cout<<"This is static display: a="<<a<<" b="<<b<<endl;
		}
		void display(){
			cout<<"This is non-static display: a="<<a<<" b="<<b<<endl;
		}
};
int test::a=10;
int main(void){
	test a;
	a.s_display();
	a.display();
	return 0;
}

用g++进行编译,提示:
error: invalid use of member ‘test::b’ in static member function
错误:在静态成员函数中错误的使用了(非静态)成员b。

但是并没有对static函数中对static变量的调用报告错误。也就是说,可以在static成员函数中调用static变量,但是不能调用非static成员变量。这是因为在对static函数调用时,可能还没有类的对象,让static函数可以调用非static变量是不合理的。
如下代码是可以正常运行的:
#include "iostream"
using namespace std;
class test{
	public:
		static int a;
		int b;
		test():b(10){}
		static void before_init(){
			cout<<a<<endl;
		}
};
int test::a=10;
int main(void){
	test::before_init();
	return 0;
}
在这个程序中,调用before_init()时还不存在test类的对象,若在before_init()函数中调用b,显然是错误的。而非static函数既可以调用非static变量,又可以调用static变量。

3.static函数和非static函数之间的互相调用

由2可知static函数不可以调用非static变量,但是非static函数可以调用非static变量。如果可以用static函数调用非static函数,岂不是间接的调用了非static变量吗?因此可以推断:非static函数可以调用static函数,而static函数不能调用非static函数。经过代码验证,此推断是正确的。

总结:对于static关键字在类中常见问题的分析,主要抓住一个顺序:即对static成员的处理是在类进行实例化之前的。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值