《Effective C++》条款2:const/enum/inline/#define的问题
该章节主要描述了#define的相关缺陷问题;
#define的主要作用主要有以下几个方面:
1.常量宏:提前进行预处理变量的定义;
2.函数宏:类似于inline函数来进行代码或者简单函数展开;
但是尽管#define可以发挥作用,仍然会有相关的缺陷;
针对于问题1的缺陷,主要是在编译报错方面存在的问题;
如果使用#define来进行变量定义,由于被预处理器转移走而非进入记号表中,会导致报错信息以常量值形式报错;
例如:#define double A=1.0;
在报错阶段,会报错1.0出现问题,所以当引用其他文件时,往往会报错信息不清楚的问题;
所以针对于第一个问题,主要的解决方法是采用const常量来替换宏;
即:const double A=1.0;
这样当出现错误信息的时候有迹可循,可以很好的担任#define的做用;
其次,需要注意的是类内静态常量的问题;
对于类内常量,由于不同编译器的不同,支持的初始化法则可能不同;
例如有些编译器支持头文件内声明定义常量值,有些只支持类外定义常量值,这往往会导致初始化问题的存在;
例如下面书上例子:
class sample {
private:
static const int NumTurns=5;
int a[NumTurns];
};
可以看到如果编译器不支持声明定义常量值,则在类内数组初始化的时候必定失败,对于该问题的解决方式可以引入enum来进行解决;
对于enum,可以通过类枚举来达到常量的效果,例如以上例子开一进行如下改写:
class sample {
private:
enum {NumTurns=5};
int A[NumTurns];
};
这种行为称之为enum hack;
enum hack除此之外还有两大做用:
1.可以有效地表面其他人或者文件撰写者引用定义的常量,例如const;
2.模板元编程的常用技术;
针对于#define的第二个问题,可以采用inline内联函数来解决;
之前总结过,inline函数主要是针对于减少函数递归调用开销而使用的方法;
编译器可以根绝inline的调用,直接展开嵌入调用部分,达到减少开销的目的;

浙公网安备 33010602011771号