實現單例模式(offer)

題目:

設計一個類,我們只能生成該類的一個實例。

解答:
單例模式的類有以下幾個特徵:
1.構造函數是private。

2.有一個唯一實例的靜態指針,且是private。

3.有一個public接口函數,獲得該唯一實例的指針。

解法一:

按照上面的特徵實現的單例類如下:

[cpp] view plain copy
  1. class Singleton{  
  2. public:  
  3.     static Singleton* getInstance();       //獲得實例  
  4. private:  
  5.     Singleton();  
  6.     static Singleton* m_pInstance;         //static聲明  
  7. };  
  8.   
  9. Singleton* m_pInstance = NULL;             //static定義  
  10. Singleton* getInstance()  
  11. {  
  12.     if (m_pInstance == NULL) m_pInstance = new Singleton();  
  13.     return m_pInstance;  
  14. }  
但是上述類存在static變量,如果在單線程模式下OK,但是在多線程模式下,就可能產生與初始化有關的“競速形勢”(條款04)。

條款04中提供了一種方法解決“競速形勢”,就是在程序的單線程啓動階段,手動調用所有reference-returning函數。這顯然有點麻煩。
以後補充多線程安全的單例模式。


解法二:利用互斥鎖

可以用一個互斥鎖將該方法鎖住,每次只能有一個線程訪問該方法,缺點是加鎖是耗時操作,效率較低。

[cpp] view plain copy
  1. class Singleton{  
  2. public:  
  3.     static Singleton* getInstance();       //獲得實例  
  4. private:  
  5.     Singleton();  
  6.     static Singleton* m_pInstance;         //static聲明  
  7. };  
  8.   
  9. Singleton* m_pInstance = NULL;             //static定義  
  10. Singleton* getInstance()  
  11. {  
  12.     lock(mutex){   //互斥鎖  
  13.         if (m_pInstance == NULL) m_pInstance = new Singleton();  
  14.         return m_pInstance;  
  15.     }  
  16. }  
效率比這個高的是加鎖前判斷實例是否已經存在。
解法三(強烈推薦):利用靜態構造函數(設計模式中的方法)

 其實一旦設置好m_pInstance就不需要同步了,因此提前創建實例,而不用延遲實例化的方法。

[cpp] view plain copy
  1. class Singleton{  
  2. private:  
  3.     Singleton();  
  4.     static Singleton* m_pInstance = new Singleton();         //static聲明  
  5. public:  
  6.     static Singleton* getInstance(){ return m_pInstance; }       //獲得實例  
  7. };  
可惜,上面會提示錯誤:a member with a in-class initializer must be const
改成下面這樣可以:
[cpp] view plain copy
  1. class Singleton{  
  2. private:  
  3.     Singleton();  
  4.     static const Singleton* m_pInstance ;         //static聲明  
  5. public:  
  6.     static const Singleton* getInstance(){ return m_pInstance; }       //獲得實例  
  7. };  
  8.   
  9. const Singleton* Singleton::m_pInstance = new Singleton();  
發佈了88 篇原創文章 · 獲贊 28 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章