Effective_C++ (條款02) 盡量以 const,enum,inline替換 #define
條款可以改為——寧可以編譯器替換預處理器,因為 #define 可能不被視為語言的一部分
#define ASPECT_RATIO 1.653
解決之道是以一個常量替換宏(#define)
const double AspectRatio = 1.653;
作為語言常量,AspecetRatio 肯定會被編譯器看到,會進入記號表內。
用常量替換 #define 有兩種特殊情況:
1. 定義常量的指針。
常量定義式通常被放在頭文件內(以便被不同的源碼含入),因此有必要將指針聲明為const。
const char* const authorName = "Scott Meyers"; // 對於char* 字符串,要寫兩次 const
const std :: string authorName( "Scott Meyers" ); // string 對象通常比其前輩 char* 合宜
2. class 專屬常量
為了將常量的作用域限制在 class 內,必須讓它成為 class 的一個成員,
為確保此常量至多只有一份實體,必須讓它成為一個 stactic 成員:
1 class GamePlayer 2 { 3 4 private: 5 static const int NumTurns = 5; // 常量聲明 6 int scores[ NumTurns ]; //使用常量 7 . . . 8 };
如果要取某個 class 的專屬常量的地址,還要提供定義式:
1 const int Gameplayer :: NumTurns; // 該式放在 實現文件 而非頭文件內
使用枚舉類型:
1 class GamePlayer 2 { 3 private: 4 enum { NumTurns = 5 }; // the enum hack — 令 NumTurns 成為5的一個記號名稱 5 int scores[ NumTurns ]; 6 . . . 7 };
使用 enum hack 的理由:
1. enum hack 的行為某些方面說比較像 #define 而不像 const。
取一個 const 的地址是合法的,但取一個 enum 的地址不合法。
實現禁止獲得一個 pointer 或 reference 指向某個整數常量
2. 實用主義
許多代碼用了它,是 模板元編程基礎技術
另一個常見的 #define 誤用情況是以它實現宏,宏看起來像函數,
但不會招致函數調用帶來的額外開銷:
1 #define CALL_WITH_MAX(a, b) f( (a) > (b) ? (a) : (b) ) // 以a,b較大值調用f
這樣長相的宏有著太多缺點。。。
我們可以獲得宏帶來的效率以及一般函數的所有可預料行為和安全性,
只要寫出 template inline 函數:
1 template< typename T > 2 inline void callWithMax( const T& a, const T& b ) // 因為不知道T是什麽, 3 { // 所以這裏采用引用傳遞 4 f( a > b ? a : b ); 5 }
你可以寫一個 class 內的 private inline 函數,而宏無法完成此事
請記住:
1. 對於單純常量,最好以 const 對象或 enums 替換 #define
2. 對於形似函數的宏,最好改用 inline 函數替換 #define
Effective_C++ (條款02) 盡量以 const,enum,inline替換 #define