条款 02:尽量以 const,enum,inline 替换 #define

条款 02:尽量以 const,enum,inline 替换 #define

Prefer consts,enums,and inlines to #defines.

宁可以编译器替换预处理器

#define ASPECT_RATIO 1.653

也许 ASPECT_RATIO 不会被编译器感知,即可能提前被预处理器移走了,导致 ASPECT_RATIO 可能没进入记号表(symbol table)中。当遇到编译错误时,可能编译器提示 1.653 而非 ASPECT_RATIO,增加排错时间。在记号式调试(symbolic debugger)中也会有相同问题。因此可以用一个常量替换上述宏。

const double AspectRaito = 1.653;

AspectRaito 作为语言常量一定会进入记号表。而且可能会比 #define 生成较小量的码。预处理器盲目替换可能导致目标码(object code)出现多份 1.653。

定义常量指针

const char* const name= "zf";

通常使用 string 对象较合宜

const std::string name ("zf");

class 中定义常量

class GamePlayer
{
private:
    static const int NumTurns = 5;  // 常量式申明
    int Scores[NumTurns];  // 使用该常量
};

上面是声明式而非定义式,如果编译器需要一个定义式时,需要提供如下定义式:

const int GamePlayer::NumTurns;  // NumTurns 的定义

#define 无法创建一个 class 专属变量,因为它不重视作用域(scope),所以也不能提供任何封装性

enum hack

旧式编译器可能会要求将初值赋在定义式

class GamePlayer
{
private:
    static const int NumTurns;  // 申明在头文件
};

const int GamePlayer::NumTurns = 5;  // 定义在实现文件

如果编译器需要在编译期间就知道一个 class 的常量值,如上述 Scores[NumTurns] 数组就要求知道 NumTurns 大小,而编译器又不支持在声明式中赋初值时,可以改用 “the enum hack” 做法

class GamePlayer
{
private:
    enum { NumTurns = 5 };
    int Scores[NumTurns];
};

其理论基础是,enum 可以被充当 int 使用,需要熟悉 enum hack 的理由:

  • enum hack 更像 #define,例如取 const 变量地址是合法的,而去 enum 的地址就不合法,有时这正是想要的,可以避免别人用 pointer 或者 reference 指向你的整数常量
  • 不够优秀的编译器可能会给 const 整数变量分配不必要的内存空间,而 enum 和 #define 则一定不会
  • 使用广泛,而且 enum hack 是模板元编程(template metaprograming)的基础技术

使用 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 inline 可以避免这些问题

template <typename T>
inline void CALL_WITH_MAX (const T&a, const T& b)
{
    f(a > b ? a : b);
}

而且 inline 遵守作用域(scope),完全可以实现 class private inline

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值