关于static const int可以在 声明时初始化的思考

         《Effective C++》中文第三版P14,有这样一个例子:

class GamePlayer{
private:
	static const int NumTurns=5;//常量声明式
	int scores[NumTurns];//使用该常量
	...
};

         文中明确指出,NumTurns为声明式而非定义式。这与我们平时理解一个变量初始化赋值后即肯定被定义,这一观念相违背。而通过实验我们发现NumTurns确实未被定义,NumTurns仅仅完成声明,并在类编译过程中被5所替代。那么为什么会出现这么奇怪的现象呢?

       1、首先需要从const谈起。我们知道由const修饰的变量其对应的数值保持恒定不变。类的成员变量,如果由const 修饰,能且只能在构造函数的初始化列表中完成初始化。例:

class A
{
	public:	
		A():a(1){}
	private:
		const a;
};

      原因在于const成员变量,它属于类生成的对象,在每一个对象中都包含了一个相应的const成员变量。在建立对象的过程中完成const成员变量的初始化。而必须在初始化列表中完成初始化则是由于当const成员变量出现在构造函数体内时默认完成的是赋值操作。这与const成员变量必须保持相应的值不变相矛盾。

       2、与const成员变量相对应的是static成员变量。当static修饰成员变量的时候,表示相应的成员变量直接属于类本身,为类生成的所有对象共有。我们在统计对象的数量时,可以通过使用static成员变量来实现。同时static相当于一个范围限定符,它限定所修饰的成员变量为该文件所特有。

         类的static成员变量,在类体外完成初始化,例:

class B
{
	public:
		B(){}
	private:
		static int a;
};
int B::a=2;//在类外初始化时,省略掉static,避免与其他全局static变量混淆

         3、既然已经有了const、static成员变量,那么static const 成员变量的产生也就顺理成章了。static const成员变量可以认为是该文件一个专属的成员变量,它属于类本身,并为所有对象、友元函数所共享。

         static const成员变量初始化方式,与static成员变量相同,例:

class C
{
	public:
		C(){}
	private:
		static const string s;
};
const string C::s="hello world";//在类体外初始化,同样省略掉static

         4、static const int NumTurns=5

         新的C++编译器对此的解释为:当一个变量为class专属的const常量,同时为整型(包括int、char、bool等),可以在声明时完成初始化操作。static const 整型变量的定义同普通的static const 成员变量,还需要在类体外完成初始化。

         回来最初的例子中:

class GamePlayer{
	private:
		static const int NumTurns=5;//常量声明式
		int scores[NumTurns];
		...
};
const int GamePlayer::NumTurns;//完成NumTurns的定义,无此句依然可以通过编译

         在过去的C++编译器中,是不允许在声明时初始化,现在几乎所有的编译器都支持这一行为。其背后的原因主要如下:
         1)类内的static const 整型变量,一般是为了完成对其他成员变量初始化操作。如本例中scores[]数组需要预先指定数组的大小,这样才能通过编译。同时,通过static const修饰的整型变量由于未定义,在编译的过程中直接被初始化的值所替代,这样可以简化内存。

         2)为了更好的替代C中的宏。C语言中的宏在预编译阶段即完成替换,static const 整型成员变量可以类似于宏那样工作,同时限定了作用域。从这方面来说,是一个更好的宏的替代方案。

         3)契合C++的设计理念。对于同一种功能要求,C++总能提供不同的解决方法以供使用。static const int 与enum遥相呼应,enum也是使用一个记号标明对应的值。使用enum的情况如下:

class GamePlayer{
	private:
		enum {NumTurns=5};//"the enum hack"——令NumTurns 成为5的一个记号名称
		int scores[NumTurns];
	...
};


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值