Item2:尽量采用const,enum,inline替代#define

1、对于宏定义"#define ABC 123"而言,在预处理阶段就把ABC全部替换成了123,ABC不会出现在符号表中。对于老式的编译器,会造成在编译过程时提示出错信息不准确的情况。

     替代方法是:const double ABC = 123;
     另外一个不大的影响是:对于浮点常量,宏定义会导致程序中出现多个浮点数的定义,导致程序略大。这个原因影响不大,可不考虑。

2、几种替代技巧

     1)字符串常量定义方法     

const char * const STR = "Here is a string.";
const std::string STR("Here is a string.");

     2)类中常量,采用静态成员变量。
          在类中定义:

static const int MAX = 5;

          在这种情况,要注意声明和定义的区别,在类中的变量都是声明。对于static变量,如果需要定义,需要在类外定义个变量(不要放在头文件):        

const int ClassName::MAX;

          对于静态const变量,如果只是用作常量,编译器会做优化(直接用值替代变量),不需要额外定义。但如果需要取该常量地址,那么就必须进行上述定义,以便给该常量分配一个内存地址(在g++中如此,但vs2010中已经不需要再额外定义)。
          类中静态常量的声明和类外的定义只能初始化一次。
          如果需要在类的声明中使用该常亮,如定义数组 nums[MAX],则必须在声明时进行初始化,而不是在定义时。
          在vs中,类声明中进行初始化的方式只适用整型常量。其它类型则要在定义中初始化。而g++无此限制(但也只限于基本类型,较复杂的类型如类等都需要进行定义)。
          所以鉴于各种限制,最好除了整型以外,所有其它类型常量都要进行额外的定义以及初始化。
     3)对于某些不支持在类定义中初始化静态整型常量的编译器,可以用枚举类型来替代宏定义。在类中定义如下:        

enum{ MAX = 5};
int nums[MAX];

          某种意义上讲,此种方式更加类似宏定义,如不能获取常量的地址,也不能定义指向常量的引用或指针。           
3、带参宏的替代方法
     1)宏的缺点:需要在实现中对参数加括号,就算加了括号也可能出现违背设计意向的情况,特别是参数是表达式的情况。另外宏的访问控制不易操作,宏定义后就一直存在,直到#undef
          
     2)替代方法:inline函数,为了实现和宏相似的效果,可以采用模板的方式定义函数。其特性和一般函数一致,并且很宏有一样的效率。

你可能感兴趣的:(C_C++)