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是个真正的函数,它遵守作用域和访问规则。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值