尽量以编译器替换预处理器
用#define实现常量
#define RATIO 1.635
缺点:
- RATIO没进入记号表内,编译器不认识,当出现编译错误时你会因为追踪1.635而浪费时间
- 对于浮点常量,常量定义比宏定义会导致较小量的代码
- #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:
- 行为比较像#define 取常量地址是合法的,取enum或#define地址不合法
- enum 和 #define一样不会导致非必要的内存分配
- 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);
}