条款二 尽量以const ,enum,inline替换#define
要替换#define首先要明确#define的主要用途:
1.用于声明常量 #define MAXSIZE 1024
2.定义一些类似于模板函数的调用 #define min(a,b) return a>b?a:b;
针对用于声明常量的用法:
存在的问题: #define是预处理器进行处理的,在使用它的时候如果出现编译错误信息,对于 #define MAXSIZE 1024的情况,提到的错误信息会是1024而不是MAXSIZE,这样
显然增加了调试的难度。
替代的方案:利用常量替代宏,const int MaxSize =1024;
替代方案的好处:首先是规避了#define定义常量宏带来的坏处,其次利用const 常量我们可以定义类专属的常量,而#define是办不到的。详细见一下代码:
class GamePlayer
{
private:
const int NumTurns=5;
int score[NumTurns];
}
const int GamePlayer::NumTurns;
如果编译器不允许在定义类的时候赋初值,那么可以改成const int GamePlayer::NumTurns=5;并且放在实现文件中。当然有的时候就是要在编译期获得数组的大小,那么enum就是一个好的选取方案:
class GamePlayer
{
private:
enum {NumTurns=5};
int scores[NumTurns];
}
这种实现方法就是我们所说的enum hack手法。
针对于#define 宏#define min(a,b) return a>b?a:b;类似的做法
存在的问题:例如 #define CALL_WITH_MAX(a,b) f( (a)>(b)?(a):(b) );有以下测试代码:
int a=5,b=0;
CALL_WITH_MAX(++a,b);
CALL_WITH_MAX(++a,b+10);
由于++a大于b,所以++a被调用了两次,而后面的那一句被调用了只有一次,造成了不明确的行为。
替代方案:模板函数
template <typename T>
inline void CallWithMAx(const T& a,const T& b)
{
return f(a>b?a:b);
}
利用inline可以像#define那样不必招致函数调用,并且也消除了不明确。