尽量以const, enum, inline替换 #define
const
在我们所编写的代码中经常会出现以下预处理命令
#define ASPECT_RATIO 1.653
注意
:但是这并不是一个好的做法,因为很可能在编译器处理源代码之前,它就被(#undef
)了这样就会造成符号名称ASPECT_RATIO
没有进入符号表(symbol table
)。
比如很可能在源代码文件的某一处会出现以下预处理命令
#undef ASPECT_RATIO
比较好的做法是以一个常量替换上述的宏,代码如下。
const double AspectRatio = 1.653
- 此时的
AspectRatio
是属于源代码的一部分因此一定可以被编译器发现- 也更方便我们去追踪
- 另一个优点是可以生成更小的码。比如,当我们使用
#define
方法时,编译器可能只是简单将ASPECT_RATIO
替换成1.653这样可能就会造成更多的目标码(object code
)
enum
对于class
的专属常量。我们既会声明它为const
同时也会声明它为static
。
比如很可能有如下代码。
class GamePlayer{
private:
static const int NumTurns = 5; // 声明常量NumTurns(不是定义式)
int scores[NumTurns]; // 使用常量NumTurns
...
};
注意
:然而这么做在某些情况下依然会发生问题,比如有些编译器会强制要求你在使用一个变量之前定义它。不然便会编译报错。
定义static变量代码如下
const int GamePlayer::NumTurns; // 之所以没有赋初值是因为static在声明时就
// 已经初始化了
注意
:可这样做的话,依然会有问题有些编译器不支持在声明式中赋初始值,于是你可能会有如下做法。
class GostEstimate{
private:
static const double FudgeFactor; // static class常量声明
// 位于.h文件内
...
};
const double // static class常量定义
CostEstimate::FudgeFactor = 1.35;// 位于.cpp文件内
注意
:间接引入了一个新问题,前面的GamePlayer
的数组坚持要在编译时间知道数组的大小。如果编译器报出“不允许static 整数型class常量完成 in class 初值设定”,则可使用enum hack
的做法
enum hack代码做法如下
class GamePlayer{
private:
enum{ NumTurns = 5};
int scores[NumTurns];
};
inline
对于max, min我们经常会用一个宏去定义。比如
#define max(a, b) ((a) > (b) ? (a) : (b))
#define min(a, b) ((a) > (b) ? (b) : (a))
注意
:这里尽管用括号将宏参数括起来了,但是依然避免不了调用出错。比如会有如下代码
int a = 0, b = 0;
max(++a, b); // a被累加2次
max(++a, b+10); // a被累加1次
以下是用inline做法
template<typename T>
inline T max(const T& a, const T& b)
{
return a > b ? a : b;
}
- 这里这样做的好处
- 不需要在函数本体中为参数加上括号
- 不需要操心参数被运算多次
- max是个函数遵守作用域(scope)和 访问规则