条款一:尽量使用const、inline而不是#define
#define ASPECT_RATIO 1.653
编译器会永远也看不到ASPECT_RATIO这个符号名,因为在源码进入编译器之前,它会被预处理程序去掉,于是ASPECT_RATIO不会加入到符号列表中。如果涉及到这个常量的代码在编译时报错,就会很令人费解,因为报错信息指的是1.653,而不是ASPECT_RATIO。
解决这个问题的方案很简单:不用预处理宏,定义一个常量:
const double ASPECT_RATIO = 1.653;
另一个普遍的#define指令的用法是用它来实现那些看起来象函数而又不会导致函数调用的宏。典型的例子是计算两个对象的最大值:
#define max(a,b) ((a) > (b) ? (a) : (b))
int a = 5, b = 0; max(++a, b);// a 的值增加了2次 max(++a, b+10); // a 的值只增加了1次
你可以用普通函数实现宏的效率,再加上可预计的行为和类型安全,这就是内联函数:
template<class T> inline const T& max(const T& a, const T& b) { return a > b ? a : b; }
--------------------------------------------------------------------------------------------------------------
预处理过程扫描源代码,对其进行初步的转换,产生新的源代码提供给编译器。可见预处理过程先于编译器对源代码进行处理,预处理指令是以#号开头的代码行。
--------------------------------------------------------------------------------------------------------------
char *s1 = "hello";
char s2[] = "hello";
char *s1 的s1,指针是指向一块内存区域,它指向的内存区域的大小可以随时改变,而且当指针指向常量字符串时,它的内容是不可以被修改的,否则在运行时会报错。
char s2[]的s2 是数组对应着一块内存区域,其地址和容量在生命期里不会改变,只有数组的内容可以改变
s2=s1; //编译出错,s2地址和容量在生命期里不能改变
s1=s2; //OK
--------------------------------------------------------------------------------------------------------------
class player { public: //常量声明式,static const static const int num = 5; int scores[num]; }; //定义式,应当放在一个实现文件而非头文件,该常量已在声明时获得初值,定义时不可以再设初值 const int player::num;
the enum hack:一个属于枚举类型的数值可以当作int使用,enum hack是模板元编程的基础技术
class game { private: enum{num = 5}; int score[num]; };