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,但是我們要合理的去使用它,上面文章有不對的地方,歡迎指正,謝謝!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章