條款2:儘量以const,enum,inline 替換 #define

 條款2:儘量以const,enum,inline 替換 #define

1、const與#define

1、1普通常量定義

#define CHANNEL_NUM 10   //宏定義

const int channel_num = 10;  //常量定義
宏定義的變量在編譯器預處理時將CHANNEL_NUM當做符號直接替換,致使該定義沒有進入符號表,導致編譯時,編譯器直接忽略對宏的安全檢查,導致代碼調試只看到數字10,沒有具體含義,而常量聲明則反。下一個條款會詳細介紹const變量。
const char * const channelName  = "GPRS";  //定義一個指向常量的常量指針

1、2類常量定義

類普通常量成員不能在類中初始化,因爲常量屬於對象,每個對象有自己的常量,且需要在構造函數的初始化列表中進行初始化,因爲常量沒有賦值之說(引用也一樣)。爲類定義一個專屬的常量,可以聲明爲靜態成員。
class Channel
{
public:
	int GetChannelNum() const
	{
		return m_num;
	}

private:
	static const int m_num = 10;
	int m_channelPool[m_num];
};
有些編譯器可以在類中直接定義靜態常量成員,但有些是需要在類外實現文件重新定義
const int Channel::m_num;

2、enum與#define

既然有些編譯器不支持在類中直接給靜態常量成員初始化,那麼在類中聲明的m_channelPool數組會因爲未知數組大小而出錯,因此我們引入enum解決這個問題。enum的詳細用法後續再寫
enum {NUM = 10};

3、inline 與 #define

#define Max(a, b) (a) > (b) ? (a) : (b)  //宏函數

inline int GetMax(int a, int b)   //內聯函數
{
	return a > b ? a : b;
}
	int a = 10;
	int b = 5;
	//int max = Max(a++, 5);
	int max = GetMax(a++, b);
	cout<<"after Max a :"<<a<<" Max:"<<max<<endl;

查看結果,發現宏函數的值不是意料到的。
    內聯函數像普通函數一樣, 要進行參考類型檢查, 但執行內聯函數要比執行普通函數更高效, 因爲調用內聯函數的地方不需要中斷調用,不需要對函數參數進行入棧和出棧開銷, 在編譯的時候, 內聯函數被嵌入到目標代碼中,與宏有同樣的效率
    宏的字符替換在預處理期間完成(由預處理器執行),導致調用Max展開爲 (a++) > (b) ? (a++) : (b),而且已經沒有類型在符號表,在編譯時不做安全檢查。








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