条款02:尽量以const,enum,inline代替#define

我们经常用define做什么?

1)  定义一个常量

2)  定义一个宏

为什么说尽量不用define。那么以这两个方面来解释:

1)  当我们定义一个常量时,我们可以用以下方式:

#define ASPECT_PATIO 1.653

我们知道编译器并没有看到ASPECT_PATIO符号(为什么?复习程序的预编译,编译,链接,运行)。于是这个记号ASPECT_PATIO并没有进行编译器的记号表内。恰巧如果我们获得了一个编译时期的错误,这个错误信息中会提到1.653而不是ASPECT_PATIO。这时,你会感到不解。

如果这个符号ASPECT_PATIO并没有定义在此文件内,则你就可能一头雾水。

引起这两种情况的原因都是:你所使用的名称可能未进入记号表。

 

怎么办?

我们可以用一个const常量来替换上面的宏。

Const double AsspectRation = 1.653;作为一个语言常量,它是被编译器看到,并记入符号表的。

 

用const 来代替define还有一个好处是可以定义一个类的专属常量。但是define没有类域的影响。

比如我们用const来定义一个类的专属常量 :

         Class GamePlayer{

                   Static const int numTurns = 5;//这是声明,由于是整型常量,所以可以在类定义内给一个初始值。

    }

Const int GamePlayer::numTurns; //这是numTurns的定义,由于之前给了初始值,这里不用再赋值了

如果你用define来定义一个常量,它不仅属于这一个类,也属于其他的类。没有封装性。

2)  定义一个宏

为什么用宏,因为宏看起来像函数,但是不会招致函数调用时带来的额外的开销。

比如定义一个两值取最大的宏

#define MAX(a,b) ( (a) >= (b) ? (a) : (b) )

这里一定要注意,宏中所有的实参要加上小括号,否则会有麻烦。

 

但是,我们可以用内联来消除这些隐患。

Template<class T>

Inline T MAX(const T& a, const T& b){

Return (a>= b ? a:b);

}

用内联的好处:没有调用函数时的开销,编译器可以对内联的代码进行优化。

 

问是不是 define就没有用了呢?

也不是的,有了const , inline使得我们对于预编译器(尤其是define)的需求降低了。但是并没有消除。#include是必需品,而#ifdef,#ifndef也继续扮演控制编译的角色。

 

 

请记住:

  •          对于单纯常量,最好以const对象或enum来代替#define.
  •          对于形似函数的宏,最好改用inline函数替换#defines.
posted @ 2012-11-15 22:26  loveyakamoz  阅读(591)  评论(0编辑  收藏  举报