[Effective cpp]-#2

prefers const, enums, and inlines to #defines

这条规则的本质是利用编译器去替换预处理器。

比如在代码中,ASPECT_RATIO可能会被编译器忽略,因为编译器在处理源码之前预处理器以及把这个标记移走,而该记号无法被记载进symbol table。所以如果遇到编译错误时,我们可能只看到1.653而无法看到ASPECT_RATIO,特别是假如改行代码是别人写的,你就更加难以发现错误了。

1
#define ASPECT_RATIO 1.653

const

  • 这时我们可以使用const取代,由于const是语言常量,因此该标记肯定会被编译器看到;
  • 另外,我们不能用#define创建一个类内常量,而const可以;
1
2
3
4
class MyClass{
private:
static const int Num = 5;//也可以只是声明const int Num; 在另一个文件内定义int MyClass:Num = 5;
}

enum

  • 假如编译不允许在类内使用static整数型常量,此时可以用the enum hack的做法;
1
2
3
4
5
class MyClass{
private:
enum {Num = 5};
int scores[Num];
}
  • 只有const声明的变量不可以取地址,而enum可以取地址;

inline

  • 这是为了取代宏定义一个函数的操作;
  • 例如:
1
2
3
4
#define CALL(a, b) f((a) > (b) ? (a) : (b))
int a = 5, b = 0;
CALL(++a, b);//a累加了两次
CALL(++a, b+10);//a累加了一次
  • 由于宏定义是直接替换,所以为了避免不必要的麻烦,我们必须为每个变量添加符号;
  • 另外这里的用法还有一个大麻烦,由于替换的原因,这里a在比较时竟然与b有关;
  • 因此我们可以用模板来代替:
1
2
3
4
5
template <typaname T>
inline void call(const T& a, const T& b)
{
f(a > b ? a : b)
}

总结

  • 对于单纯变量,最好用const或者enum取代#define
  • 对于函数宏,可以用inline函数代替