基本上使用預處理指令#define的地方都可以使用const,enum或者inline來替換掉它。主要的原因有兩個:
#define ASPECT_RATIO 1.653
1.預處理指令是在編譯前就進行預處理的(gcc -E進行預處理,它的輸出文件作為gcc -S進行編譯的輸入),所以編譯器是看不到#define定義的符號ASPECT_RATIO ,故它不會出現在符號表中,這樣如果編譯期間出現了錯誤它可能只提示常量1.653,如果這個文件又不是你寫的,那麼調試會很困難。
2.使用常量可能比使用#define產生更少的代碼,#define進行替換的時候會將ASPECT_RATIO 都替換成1.653,這樣在目標代碼中會出現多個1.653,但是使用const就不會有這個問題。
基於以上兩個原因應該盡可能在使用#define的時候替換成const,enum,或者inline
使用const替換
如果需要在一個類中使用一個常量,可以在類內定義一個static const的常量來避免使用#define。static和const這兩個關鍵字可以參考之前的這篇博客。
class GamePlayer { private: static const int intNum=5;//常量聲明式 int scores[intNum];//使用該常量 };
const int GamePlayer::intNum;//定義
如果這個常量不是整型的,那麼它不能在類中就賦初值,只能在實現文件中賦初值。但是如果編譯器不支持整型在聲明時就指定一個初值,可以使用枚舉類型來替代。
使用enum替換
class GamePlayer { private: enum {NumTurns=5 }; int scores[NumTurns];//使用枚舉類型 };
使用inline替換
#define可以用來實現宏:
#define MAX(a,b) ((a)>(b)?(a):(b))
使用宏的好處是它不會帶來函數調用時的開銷,但是這個問題可以通過inline關鍵字和模板來解決。使用上面的宏會有一個不可避免的問題:
int a=5,b=0;
MAX(++a,b);//a被累加一次
MAX(++a,b+10);//被累加兩次
上面的宏可以通過函數模板來解決這個問題,它即避免了函數調用的開銷,也解決了宏的問題:
templateinline void max(const T & a,const T & b)//注意這裡使用常量引用的形式 { return a>b?a:b; }