1. 程式人生 > >C++慎用define,以及相關的替代的方法

C++慎用define,以及相關的替代的方法

在C++中,巨集是一個非常好用的預處理功能,同時,它又有一些不好的地方,特別是用#define來實現macros,如果你這樣做的話,你肯定要為每個引數都加上小括號,否則你懂得。但是這樣仍然存在問題,說一個最近看到的例子:
/*求兩個變數中最大的那個*/
#define THE_MAX(a, b) f((a) > (b) ? (a) : (b))

看著就頭疼好吧- -!
當你這樣用的時候:

THE_MAX(++a, ++b);

如果有人這樣使用了這個巨集,那麼很明顯的是,a和b總有一個會多累加一次。
那先總結一下#define的缺點吧,優點就不說了- -!

  1. #define不重視scope的概念,或者說沒有,一旦被定義,就一直有效,除非在某個地方被#undef;
  2. 由於1的原因,#define不提供封裝性,也就沒有private這種許可權之類的;
  3. 由於是預處理命令,所以定義的符號不會進入符號表內,對於除錯的過程,很可能會讓你頭疼;

#define的替代

1.對於#define I_VAR 123

const int iVar = 123可以替換上面的巨集
有兩個需要注意的地方:
(1) 當定義的是常量指標,需要const兩次( const char* const iVar = "C++"),第一個const是防止值被改變,第二個const防止地址被改變。
(2) 當定義到class內時,需要用static來修飾這個變數,防止出現多個實體,程式碼如下:
class A {
private:
    int i;
    doubel d;
    static const iVar = 15;
    ...
};

還有一個需要說一下,有些編譯器需要你在.cpp檔案內去定義這個常量:A::iVar;
由於宣告時已經指定了值,所以定義時不要再去賦值,當然你也可以在宣告時不指定任何值,而在定義時在確定這個值。

2. 對於#define FUNC(a, b) f((a) > (b) ? (a) : (b))

可以寫一個inline函式來替代:

template<typename T>
inline void func(const
T& a, const T& b) { f(a > b ? a : b); }

最後,我們仍然離不開#define,但是我們要合理的去使用它,上面文章有不對的地方,歡迎指正,謝謝!