条款02:尽量以const,enum,inline替换#indefine

结论1:对于单纯常量,最好以const对象或enum替换#define

原因如下:#define定义的宏名称在编译器开始处理源代码前会被预处理器替换为字面值常量,从而使#define定义的宏名称没入进入记号表,当运用这些宏名称获得编译错误信息时,会带来困惑。另一方面,预处理器盲目地将宏名称替换,导致目标码出现多份字面值常量,而const对象则不会出现这种情况。

有两种特殊情况值得注意,第一是定义常量指针时,必须将指针而不是指针所指之物声明为const。第二是定义class专属常量,必须让常量成为class的一个成员,将常量的作用域限制于class内,而为确保常量至多只有一份实体,还必须让它成为一个static成员,而#define是无法创建一个class专属常量的。例如:

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

在上面的代码中,”static const in NumTurns = 5;“为声明式而非定义式,通常C++要求所使用的任何东西都要提供一个定义式,但如果是class专属常量又是static且为整数类型,只要不取它们的地址,则可以只声明并使用它们而无须定义式。但如果需要取class专属常量的地址,或编译器坚持要看到一个定义式,则须在实现文件而非头文件中提供定义式如下:

const int GamePlayer::NumTurns;//常量定义式,因已在声明时获得初值,故定义时不可再设初值。

事实上,在VS2010中,即使取class专属常量的地址,也可以只声明并使用它们而无须定义式。

上述NumTurns在声明式中设定初值的做法称为"in-class 初值设定“,只允许对整数常量进行,另外,如果编译器不允许static成员在声明式获得初值,则可以将初值放在定义式中,例如:

class CostEstimate {
private:
static const double FudgeFactor; // static const 常量声明,位于头文件内
}

const double CostEstimate::FudgeFactor = 1.35; // static const 常量定义,位于实现文件内


如果编译器不允许"static 整数型class常量"完成”in-class 初值设定",可采用所谓"the enum hack"补偿做法,其理论基础是:"一个属于枚举类型的数值可权充ints使用”,例如:

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

“enum hack”的好处有两方面:第一,enum hack的行为某方面比较像#define而不像const,例如取一个const的地址是合法的,但取一个enum的地址是不合法的,取一个#define的地址也是不合法的。第二,实用主义,许多代码用了它,也是"template metaprogramming"的基础技术。

结论2:对于形似函数的宏,最好改用inline函数替换#define。

原因如下:inline函数可以获得宏带来的效率以及一般函数的可预料行为和类型安全性。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值