.h文件:#pragma once/****************************** @filename: Singleton.h* @author: kzf* @version: 1.0* @date: 2011/11/14 * @describe...
.h文件:
#pragma once /***************************** * @filename: Singleton.h * @author: kzf * @version: 1.0 * @date: 2011/11/14 * @describe: 單鍵模式 保證唯一的實例 如果你整個程式是單線程的,那麼標準模式或Meyers單例模式是你最佳選擇 * @modification:無 *****************************/ //標準模式 class CSingleton1 { private: //構造函數及析構函數私有化 CSingleton1(); virtual ~CSingleton1(); private: //防止拷貝構造 以及 賦值 操作 CSingleton1(const CSingleton1 &ob); CSingleton1& operator=(const CSingleton1 &ob); private: static CSingleton1* m_pInstance; public: static CSingleton1* GetInstance(); static void ReleaseInstance(); void Print(); }; /** 標準模式的優缺點: 優點: 屬於“懶漢”單例模式,第一次調用GetInstance才分配記憶體,不調用則不分配記憶體 缺點: 1)GetInstance中每次需要判斷是否=NULL 2)由於指針動態分配,必須手動調用ReleaseInstance釋放 3)多線程不安全,有可能實例化多個記憶體對象 **/ //Meyers單例模式 class CSingleton2 { private: //構造函數及析構函數私有化 CSingleton2(); virtual ~CSingleton2(); private: //防止拷貝構造 以及 賦值 操作 CSingleton2(const CSingleton2 &ob); CSingleton2& operator=(const CSingleton2 &ob); private: int m_nTestNum; public: static CSingleton2& GetInstance(); void Print(); }; /** Meyers單例模式的優缺點: 優點: 1)屬於“懶漢”單例模式,第一次調用GetInstance才實例化 2)GetInstance中不需要判斷是否=NULL,效率提高 3)使用對象不是指針分配記憶體,不會記憶體泄漏 4)多線程下能確保實例化一個記憶體對象 缺點: 1)多線程下未真正意義上同步。 這是因為C++中構造函數並不是線程安全的。 C++中的構造函數簡單來說分兩步: 第一步:記憶體分配 第二步:初始化成員變數 結論:Meyers方式雖然能確保在多線程中產生唯一的實例,但是不能確保成員變數的值是否正確. **/ /** 從單例模式實現的角度考慮: 1、總是避免第三方調用拷貝構造函數以及賦值操作符 2、總是避免第三方調用構造函數 3、儘量避免第三方調用析構函數 4、總是需要一個靜態方法用於全局訪問 **/
.cpp文件:
#include "StdAfx.h" #include "Singleton.h" //----------------------標準模式---------------------------- CSingleton1* CSingleton1::m_pInstance = NULL; CSingleton1::CSingleton1(void) { printf("Construct begin\n"); //假設各種變數的初始化操作,花費近1s時間 用Sleep進行模擬 Sleep(1000); printf("Construct end\n"); } CSingleton1::~CSingleton1(void) { printf("Destruct\n"); } CSingleton1::CSingleton1(const CSingleton1 &ob) { // } CSingleton1& CSingleton1::operator =(const CSingleton1 &ob) { if (&ob != this) { } return *this; } CSingleton1* CSingleton1::GetInstance() { if (NULL == m_pInstance) { m_pInstance = new CSingleton1; } return m_pInstance; } void CSingleton1::ReleaseInstance() { if (NULL != m_pInstance) { delete m_pInstance; m_pInstance = NULL; } } void CSingleton1::Print() { printf("print out CSingleton1\n"); } //----------------------Meyers單例模式---------------------------- CSingleton2::CSingleton2(void) { m_nTestNum = 0; printf("Construct begin,testnum=%d\n", m_nTestNum); //假設各種變數的初始化操作,花費近1s時間 用Sleep進行模擬 Sleep(1000); m_nTestNum = 100; printf("Construct end,testnum=%d\n", m_nTestNum); } CSingleton2::~CSingleton2(void) { printf("Destruct\n"); } CSingleton2::CSingleton2(const CSingleton2 &ob) { // } CSingleton2& CSingleton2::operator =(const CSingleton2 &ob) { if (&ob != this) { } return *this; } CSingleton2& CSingleton2::GetInstance() { //使用局部靜態變數方式,從而使之延遲到調用時實例化 static CSingleton2 gInstance; return gInstance; } void CSingleton2::Print() { printf("print out CSingleton2 testnum=%d\n", m_nTestNum); }