D45.1.0 尽量用const enum inline 替换 #define
01 使用const替换#define
通常,我们很习惯在程序起始位置写出#define ASPECT_RATIO 1.653
的语句。这样的定义往往会有如下隐患:
ASPECT_RATIO从未被编译器看见,可能在编译器开始处理源码之前就被预处理器移走了。名称
ASPECT_RATIO
可能没进入记号表内,于是会出现变异错误的信息。当
ASPECT_RATIO
定义在一个非我们缩写的文件头内时,然后我们肯定要花时间去寻找1.653
来自哪里。
使用如下定义:
const double AspectRatio = 1.653;
作为一个常量,AspectRatio肯定会被编译器看到,当然就会进入记号表内。此外对浮点常量而言,使用常量可能比使用#define
导致较小的量的码,因为预处理器“盲目地将宏名称ASPECT_RATIO替换为1.653
”可能导致目标码出现多份1.653。
02 使用enum替换#define
#define NumTurns 5
class GamePlayer
{
private:
int scores[NumTurns];
}
上述代码中,我们无法利用#define
创建一个class专属常量,因为一旦宏被定义,它就在后面的编译过程中有效。#define
不仅不能够用来定义class常量,也不能提供任何封装性。这时候可以使用枚举类型,其理论基础是“枚举类型的数值可以充当int型使用”。于是,GamePlayer
可定义如下:
class GamePlayer
{
private:
enum { NumTurns = 5 };
int scores[NumTurns];
}
使用enum可以防止别人获取整数常量的地址或者引用,因为获取enum的地址是不合法的,而获取const的地址是合法的。
03 使用inline替换#define
宏还可以用来实现函数定义,如:
//a和b较大值调用f
#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被累加一次
上面的代码中,调用f之前,a的递增次数取决于b。通过使用template inline函数可以获得宏带来的效率以及一般函数所有可预料行为和类型安全:
template<typename T>
inline void callwithMax(const T& a, const T& b)
{
f(a>b?a:b)
}
这个template产出一群函数,每个函数都接受两个同型对象,并以其中较大者调用f。这种写法方便阅读,并且callwithMax是个真正的函数,它遵守作用域和访问规则。
上一篇: define宏定义详解
下一篇: c中宏定义
推荐阅读
-
D45.1.0 尽量用const enum inline 替换 #define
-
条款02:尽量以const,enum,inline替换#define
-
Effective C++笔记之二:尽量以const、enum、inline替换#define
-
Effective C++ 条款02 尽量以const,enum,inline替换#define
-
《Effective C++》读书笔记 条款02 尽量以const,enum,inline替换#define
-
条款02:尽量以const,enum,inline替换#define
-
条款02:尽量以const,enum,inline 替换 #define
-
《Effective C++》读书笔记 条款02 尽量以const,enum,inline替换#define