標籤:
轉自:http://blog.csdn.net/hackbuteer1/article/details/7460019
單例模式其意圖是保證一個類僅有一個執行個體,並提供一個訪問它的全域訪問點,該執行個體被所有程式模組共用。
《設計模式》一書中給出了一種很不錯的實現,定義一個單例類,使用類的私人靜態指標變數指向類的唯一執行個體,並用一個公有的靜態方法擷取該執行個體。
class CSingleton{private: CSingleton() //建構函式是私人的 { } static CSingleton *m_pInstance;public: static CSingleton * GetInstance() { if(m_pInstance == NULL) //判斷是否第一次調用 m_pInstance = new CSingleton(); return m_pInstance; }};
GetInstance()使用懶惰初始化,也就是說它的傳回值是當這個函數首次被訪問時被建立的。
上述代碼可能存在的問題:
m_pInstance指向的空間什麼時候釋放呢?更嚴重的問題是,該執行個體的解構函式什麼時候執行?
一個妥善的方法是讓這個類自己知道在合適的時候把自己刪除,或者說把刪除自己的操作掛在作業系統中的某個合適的點上,使其在恰當的時候被自動執行。
我們知道,程式在結束的時候,系統會自動析構所有的全域變數。事實上,系統也會析構所有的類的靜態成員變數,就像這些靜態成員也是全域變數一樣。利用這個特徵,我們可以在單例類中定義一個靜態成員變數,而它的唯一工作就是在解構函式中刪除單例類的執行個體
class CSingleton{private: CSingleton() { } static CSingleton *m_pInstance; class CGarbo //它的唯一工作就是在解構函式中刪除CSingleton的執行個體 { public: ~CGarbo() { if(CSingleton::m_pInstance) delete CSingleton::m_pInstance; } }; static CGarbo Garbo; //定義一個靜態成員變數,程式結束時,系統會自動調用它的解構函式public: static CSingleton * GetInstance() { if(m_pInstance == NULL) //判斷是否第一次調用 m_pInstance = new CSingleton(); return m_pInstance; }};
類CGarbo被定義為CSingleton的私人內嵌類,以防該類被在其他地方濫用。
程式運行結束時,系統會調用CSingleton的靜態成員Garbo的解構函式,該解構函式會刪除單例的唯一執行個體
添加一個類的靜態對象,總是讓人不太滿意,所以有人用如下方法來重新實現單例和解決它相應的問題,代碼如下:
class CSingleton{private: CSingleton() //建構函式是私人的 { }public: static CSingleton & GetInstance() { static CSingleton instance; //局部靜態變數 return instance; }};
使用局部靜態變數,非常強大的方法,完全實現了單例的特性,而且代碼量更少,也不用擔心單例銷毀的問題。 但使用此種方法也會出現問題,當如下方法使用單例時問題來了, Singleton singleton = Singleton :: GetInstance(); 這麼做就出現了一個類拷貝的問題,這就違背了單例的特性。產生這個問題原因在於:編譯器會為類產生一個預設的建構函式,來支援類的拷貝。
最後沒有辦法,我們要禁止類拷貝和類賦值,禁止程式員用這種方式來使用單例,函數的代碼改為如下:
class CSingleton{private: CSingleton() //建構函式是私人的 { }public: static CSingleton * GetInstance() { static CSingleton instance; //局部靜態變數 return &instance; }};
可以顯示的聲明類拷貝的建構函式,和重載 = 操作符,新的單例類如下:
class CSingleton{private: CSingleton() //建構函式是私人的 { } CSingleton(const CSingleton &); CSingleton & operator = (const CSingleton &);public: static CSingleton & GetInstance() { static CSingleton instance; //局部靜態變數 return instance; }};
c++中的單例模式