Effective C++ T02:尽量以const、enum、inline替代 #define

38 篇文章 0 订阅
31 篇文章 2 订阅

Effective C++学习笔记总链接

改善程序与设计的55个具体做法学习笔记-每日1条


条款02:宁可以编译器替代预处理器

技巧

对于单纯常量,最好用const对象和enum替换#define

对于形似函数的宏,最好改用inline函数替代#define


宏定义(#define)的问题

#define ASPECT_RATIO 1.653 //宏定义
//const 常量
const double AspectRatio = 1.653; // 大写名称通常用于宏,这里改变名称写法。

1. 你所用的名称可能并未进入记号表

仅仅是将ASPECT_RATIO 替换成1.653,当你运用此常量但获得一个编译错误信息时,错误信息会提到1.653而不是ASPECT_RATIO。而const常量 AspectRatio 会被编译器看到,进入记号表。

2. 使用常量可能比使用#define 导致较小量的码

原因:预处理器会将 ASPECT_RATIO 替换成1.653,可能导致目标码出现多份1.653,而AspectRatio 只有一份

3.#define不能提供封装性

无法利用#define 创建一个class 专属常量,一旦宏被定义,它就在其后的编译过程中有效(除非在某处被#undef)。

4. 形似函数的宏,但不会招致函数调用带来的额外的开销

无论何时你写出宏,必须记住为宏中的所有实参 加上小括号
因此,建议使用内联函数(inline)

但是并不能完全消除宏,仍然在#ifndef/#ifdef扮演重要角色。

常量代替#define

定义常量指针

常量定义式通常放在头文件中,有必要将指针声明为双const(而不只是指针所指之物)。例如:

const char* const authorName = "Scott Meyers";
//...
const std::string authorName("Scott Meyers");

值得注意std::string 对象通常比char*合宜

class 专属常量

为了将常量的作用域限制于class内。 必须让它成为class的成员,而为了确保此常量至多只有一份实体,必须让他成为一个static成员

class GamePlayer{
private:
	static const double NumTurns; // static class 常量声明,位于头文件中
	int scores[NumTurns]; //错误,编译器必须在编译期知道数组的大小。可以用 enum常量
};

const double GamePlayer::NumTurns = 1.35 //  static class 常量定义,位于实现文件中

enum常量

格式

class GamePlayer{
private:
	enum{ NumTurns = 5 }; // 令NumTurns成为5的一个记号名称
	int scores[NumTurns]; //ok
};

区别,const常量取地址合法,而取enum和#define地址不合法

enum常量为了实用主义。“enum hack”是模板元编程的基础技术(见条款48)

inline 代替 #define

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

宏必须加上小括号,否则可能遭遇麻烦。

#define CALL_WITH_MAX(a, b) f((a)>(b)?(a):(b))
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值