C++编程守则—尽量以const,enum,inline替换#define
简介
遵循守则,养成良好的编程习惯。该规则主要摘抄总结自《Effective C++》这本书,也许把题目改为“宁可以编译器替换预处理器”比较好。因为#define不被视为语言的一部分。这正是他的问题所在。
以const替换#define
当我们做出如下事情时:#define ASPECT_RATIO 1.653
记号名称ASPECT_RATIO 也行从未被编译器看见,当运行此常量获得一个编译错误信息时,这个错误信息也许会提到1.653而不是ASPECT_RATIO,如果ASPECT_RATIO被定义在非你所写的头文件内,可能就会因为追踪他而浪费时间。
解决之道是以一个常量替换(#define):
const double AspectRatio= 1.653;
作为一个语言常量,AspectRatio肯定会被编译器看到,此外,使用常量可能比使用#define导致较小量的码,因为预处理器“盲目地将宏名称ASPECT_RATIO 替换为1.653”可能导致目标码出现多份1.653,若改用常量AspectRatio绝不会出现相同的情况。
class专属常量:
class GamePlayer{
private :
static const int NumTurns;
...
};
在实现文件中提供如下定义式:const int GamePlayer::NUmTurns = 5;#define无法设置专属常量,一旦宏被定义,它在其后的编译过程有效(除非在某处被#undef)。
以enum替换#define
如下示例:一个枚举类型的数值可权充ints被使用
class GamePlayer{
private :
enum { NumTurns = 5 };
int scores[NumTurns ];
...
};
以inline替换#define
以下表达式为例:#define CALL_WITH_MAX(a,b) f((a) > (b) ? (a) : (b))
必须记住:宏中所有实参需加上小括号,否则可能会遇到麻烦。但如下情况需多加注意:
int a = 5,b = 0;
CALL_WITH_MAX(++a,b); //a被累加二次
CALL_WITH_MAX(++a,b+10); //a被累加一次
为了获得宏所带来的效率以及一般函数所有可预料行为和类型安全性,可用如下表示:
template<typename T>
inline void callwithMax(const T& a, const T& b)
{
f(a > b ? a : b);
}
最后请记住
- 对于单纯常量,最好以const对象或enums替换#defines
- 对于形似函数的宏,最好改用inline函数替换#defines