条款02:尽量以const、enum、inline替换#define
该条款换另一种说法是:宁使用编译器也不使用预处理器。原因在于:#define不被视为语言的一部分。例如:
#define DATA 13
其中,DATA从来没被编译器所看见,在预处理的过程中所有的DATA都被替换成了13,于是DATA从来没有记录在符号表内。当程序出在13这里出现错误的时候,错误信息只会提示13有错误而不会提到DATA,如果头文件不是你写的时候,你会感到很困惑。并且define不会做类型检查。
解决方法:利用const代替define
cosnt和define的区别:
(1)const在编译阶段处理,define在预处理阶段进行替换;
(2)const有具体类型,define没有具体类型;
(3)const会做类型检查,define不做类型检查;
(4)const会分配内存,define不会分配内存。
用const替换#define时的两种特殊情况:
(1)定义常量指针的时候:
const char* const str=“hello”;
其中,这里的两个有const,表示被指物和指针本身都不可修改。上面出现的代码最好用下述代码:
const string str(“hello”);
(2)class专属常量,将常量的作用域限制在class内,为了保证const常量只用一份实体,将该常量声明为static。
class Test
{
private:
static const int data; //data声明;
};
const int Test::data=10; //data的定义;
注意:当用宏体是一个函数的时候,特别要注意的是:该宏中的每一个参数都应该加上括号要不然会出现意想不到的结果。解决方法:利用内联函数来处理。
关于inline函数一些说明:
(1)当某个函数的只有几行的时候,可以将函数定义成内联函数,这样省去了函数入栈和出栈带来的开销。
(2)在class内定义的函数都将自动转换成内联函数。
什么情况下不能使用内联函数:
(1)函数体比较大的情况下;
(2)函数体出现循环或递归的情况;