單例模式也稱爲單件模式、單子模式,其應用場景是程序中需要寫個類,而這個類只能產生一個實例。這個實例在全局被所有類都能夠調用到,這個時候我們所使用的就是單例模式。該實例被所有程序模塊共享。有很多地方需要這樣的功能模塊,如系統的日誌輸出等。
而一個實例的實現方式有很多種,可以通過全局變量來實現,但這樣的代碼顯得很不雅觀。
下面舉個C/S架構中客戶端中用到的單例模式,這個客戶端與服務器之間網絡通信採用windows socket實現。而客戶端程序中之需要一個socket就可以實現與服務器端通信,故一個客戶端只需要開啓一個socket,寫一個類封裝封裝這個socket,封裝socket的這個類就可以採用單例模式。下面說說單例模式的特點。
單例模式的要點有三個;一是某各類只能有一個實例;二是它必須自行創建這個事例;三是它必須自行向整個系統提供這個實例即以下特徵:
u 它有一個指唯一實例的靜態指針m_pInstance,並且是私有的。
u 它有一個公有的函數,可以獲取這個唯一的實例,並在需要的時候創建該實例。
u 它的構造函數是私有的,這樣就不能從別處創建該類的實例
以客戶端封裝socket的TKCommunication類爲例,如下:
class TKCommunication
{
public:
virtual ~TKCommunication();
int Initialize(DWORD dwAddr, int iPort, HWND hWnd);
void Finalize();
int RecvData(char *strRecv, int &iNumRecv);
int SendData(const char *send);
static TKCommunication* GetInstance();
private:
TKCommunication();
static TKCommunication* m_TKComm;
SOCKET m_Socket;
HWND m_hMainWnd;
};
TKCommunication類中的TKComm成員變量就滿足唯一指向實例的靜態指針。
構造函數TKCommunication();爲私有函數,這樣保證了實例不能在別處被創建。公有函數GetInstance()用以獲取這個唯一實例,並在需要的時候創建,並且保證只有一個實例。
部分實現代碼如下:
//用以初始化私有靜態成員變量
TKCommunication* TKCommunication::m_TKComm = NULL;
//爲程序調用提供實例入口,並在需要的時候創建實例。
TKCommunication* TKCommunication::GetInstance()
{
if(NULL == m_TKComm)
{
m_TKComm = new TKCommunication();
}
return m_TKComm;
}
當程序中調用這個實例用以接收發送數據時,只需執行
iRet = TKCommunication::GetInstance()->RecvData ((char *)m_Msg);
iRet = TKCommunication::GetInstance()->SendData((char *)m_Msg);
最後,感謝高成eason提供例子。