2.尽量用const, enum, inline代替#define -- Prefer const, enum, inline to #define.

  1. 我们都知道,#define PRICE 30 是预编译处理器进行预编译的时候执行的,无法在编译器进行编译的过程中看见,因此,当编译出错的时候,通常错误信息是提到30,而不是PRICE,因此程序员很难定位到出错的位置。

  解决方法是以const代替#define:const int Price = 30; Price肯定可以被编译器看到,因此不会导致上述错误。

  2. 为了将常量的作用域限定于一个类中使用,并且只有一份数据,通常定义一个static成员变量(#define无法做到这点):

    class A

    {

      private:

        static const int Count = 5;  // const声明式

        int stu[Count];        // 使用该const

    };

   Count是一个声明式而非定义式,如果要使用定义式,通常定义如下:const int A::Count; // 不要赋值,因为声明时已赋初值。将定义式放在实现文件,而不是头文件中。

  3. enum可以代替const在2中的实现, enum { Count = 5 }; 此外enum还可以约束Count不被pointer, reference所指向。这也是template metaprogramming的基础技术。

  4. 关于#define的一个误用就是实现宏,macros看起来像个函数,但是不会导致函数调用带来的额外开销。

    #define MAX(a, b) max( (a) > (b) ? (a) : (b)) // 千万不要忘记括号

  光看到这个宏,我就头大了,除了会带来忘记括号的风险之外,还会产生你意想不到的错误结果:

    int a = 3, b = 1;

    MAX(++a, b)        // a被累加2次

    MAX(++a, b + 10)    // a被累加1次

  Oh,my god!!! a的累加次数竟然取决于a所比较的对象!!!通常为了避免错误,我们都是通过inline来实现的:

  template <typename T> inline void Max(const T& a, const T& b)

  {

    f(a > b ? a : b);

  }

  怎么样,是不是轻松多了?此外还能设置inline的访问权限,#define永远都无法达到这点。

 

  请记住:对于单纯的常量,最好用const, enum替换#define。

      对于类似于函数的宏,最好用inline替换#define。

posted @ 2012-05-22 22:05  nchxmoon  阅读(343)  评论(0编辑  收藏  举报