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

尽量以编译器替换预处理器

用#define实现常量

#define RATIO 1.635

缺点

  1. RATIO没进入记号表内,编译器不认识,当出现编译错误时你会因为追踪1.635而浪费时间
  2. 对于浮点常量,常量定义比宏定义会导致较小量的代码
  3. #define 无法创建一个class专属常量

好的做法:用常量代替宏
const double RATIO = 1.635

// 常量字符串
const char* name = "zhliu"
// 更好的做法:
const std::string name("zhliu");

class专属常量

class Msg{
private:
	static const int Len = 5; //声明式而非定义式
	char data[Len];
	...
};

通常C++要求你对使用的任何东西都提供一个定义式,但class专属整型staic常量特殊处理,无需定义式。
但如果需要对该常量取地址或编译器(错误的)要求看到一个定义式,就必须在实现文件中提供定义式:

const int Msg::Len;//定义式,无需赋值,声明时已提供初值

旧式编译器也许不支持static成员在其声明式上获得初值,“in-class初值设定”也只允许对整数常量进行,这时就只能将初值放在定义式。
但如果class编译期间必须要一个class常量值时,如上文中的LEN,则可用"the enum hack"做法。

enum { Len = 5 };

enum-hack:

  1. 行为比较像#define 取常量地址是合法的,取enum或#define地址不合法
  2. enum 和 #define一样不会导致非必要的内存分配
  3. enum-hack是模板元编程的基础技术

#define 实现宏函数

优点:不会招致函数调用带来的额外开销
缺点:在表达式中不安全,宏中的所有实参需要带上小括号,即使如此,在特殊情况下,也会出错

#define CLL_WITH_MAX(a, b)             f((a) > (b) ? (a) : (b))

int a = 5, b = 0;
CLL_WITH_MAX(++a, b);   //a被累加两次
CLL_WITH_MAX(++a, b+10);//a被累加一次

正确做法:
使用(template)内联函数代替

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

猜你喜欢

转载自blog.csdn.net/lzhtcsw2016/article/details/88304298