EffectiveC++学习笔记-条款2

时间:2022-12-25 22:05:39

条款1就不说了,大致看一下就ok。

条款2 尽量用const、enum、inline代替#define

#define ASPECT_RATIO 1.653
宏不进入符号表,所以可能调试的时候,对这个1.653一脸蒙蔽,于是浪费时间找它。。
最好使用
const double AspectRatio = 1.653 // 代替上面的宏
并且它会进入符号表,也不会导致object code出现多份1.653

第二点要注意的是class的专属常量问题。
保证次常量只有一份必须要让他成为一个static成员:

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

有些时候“一个属于枚举类型的数值可权冲ints被使用”

class GamePlayer{
private:
enum { NumTurns = 5}; //NumTurns成为了5的一个记号位置
int socres[NumTurns]; //使用该常量
}

我们可以从这个代码中看出:这个NumTurns其实更像#define而不像const,有时候这是我们需要的。例如取一个const地址是合法的但是取一个enum地址就不合法,取#define的地址同常也不合法。
如果你不想让别人获取一个pointer或者reference指向你的某个整数常量,enum可以实现这个约束。

第三点需要注意的是宏函数
例如(一定多注意这个例子)

#define square(a)   (a)*(a)

遇到square(++v)就会出问题
可使用

template <class T>
T square(const T& v)
{
return v * v;
}

模板形式代替 但是!!!!!很关键
函数调用有一个保存现场和恢复现场的过程(本质是栈的压入和弹出),频繁地调用会导致性能低下,解决方法是在函数前面加上inline关键字,像这样:

template <class T>
inline T square(const T& v)
{
return v * v;
}

这样就告诉编译器了,我想牺牲空间换时间——把这段函数体部分直接替换到原代码中,就不要保存现场和恢复现场了。但这里注意,inline并不是强制的,就算你用了inline,编译器也不一定100%地进行代码替换,
比如递归函数,编译器会直接忽略掉你加的inline。所以,inline只是向编译器建议进行代码内联而已,inline适合于函数体本身短小(无递归)且频繁调用的场景

重点

//const适合单个变量定义
double const PI = 3.1415926

//enum适合一组相关变量
enum WEEK
{
...
}
  1. 对于单纯常量,最好以const对象或enums替换#defines
  2. 最好用inline替换宏函数