條款02:儘可能以const、enum、inline替換#define;儘量用編譯器代替沒必要要的預處理器。函數
1、對於單純常量spa
一、const指針
有兩種特殊的const,常量指針和class專屬常量;code
又分爲常量指針、指針常量、指向常量的指針常量;blog
本質是個指針,是指向一個常量的指針,也即指向的內容(*p)不可變。作用域
本質是個常量,是形容這個常量的類型是指針,也即指針指向不能改變。編譯器
實際栗子解釋:編譯
const double *p = &b 常量指針;不容許 *p = 6.66,由於常量指針的指向內容是常量不可變;可是容許 p = &c。class
double * const p = &b 指針常量;不容許 p = &c,由於指針常量的指向是常量不可變;可是容許 *p = 6.66。基礎
class專屬常量是指常量的做用域只在class裏,須要在const的基礎上再添加static關鍵字。
.h頭文件裏聲明 static const double score;
.cpp實現文件裏設初始值 const double Student::score = 66.6;
(不少編譯器不支持在聲明的時候設置初始值,只能將聲明和設初值分開)
二、enum
若是遇到上述「不支持在聲明的時候設置初始值」,就展示了enum的必要性。
eg:
class A { private: static const int LEN = 5; int score[LEN]; };
若是編譯器(錯誤地)不容許static整數型class常量完成 in-class 初值設定,就應該用enum來代替:
class A { private: enum {LEN = 5}; int score[LEN]; };
2、對於形似函數的宏
將簡單的函數寫成宏,能免去函數調用的一些開銷,可是使用不當會獲得預料以外的結果。
有個經典的宏問題:
#define FINDMAX(a,b) ( (a) > (b) ? (a) : (b) ) FINDMAX(a++,b); //a被累加兩次 FINDMAX(a++,b+10); //a被累加一次
用 inline 來代替此類宏的使用,既能免去函數調用的開銷,也能避免一些不可預知的錯誤。
inline 將函數「內聯」 起來了,在調用的時候是編譯器使用相應的函數代碼替換函數調用。編譯器在調用一個內聯函數時,會首先檢查它的參數的類型,保證調用正確。而後進行一系列的相關檢查,就像對待任何一個真正的函數同樣。這樣就消除了相似#define的隱患和侷限性。
template <typename T> inline T FindMax(const T& a, const T& b) { return a>b?a:b; }
一、對於單純常量,儘可能用const、enum替換#define;
二、對於形似函數的宏,最好用inline函數代替#define;