模板singleton模式的C++實現


模板singleton模式的C++實現

  近期回過頭整理了一下singleton模式,看了別人寫的關於singleton的介紹。發現這個singleton模式雖然簡單,但要寫一個穩定/線程安全/泛型的模板singleton,還是需要一點技巧的。經過整理,要寫一個模板的singlton至少需要以下幾個知識點:

1:singleton

2:static類成員實例延遲創建。

3:static類實例創建互斥實現,即線程安全。

4:double check技巧。  【Ref:http://www.ibm.com/developerworks/library/j-dcl/index.html】

5:模板。

6:static成員變量初始化。

7:singleton關閉類實例

下面上singleton實現代碼,測試可用。

 1 #pragma once
 2 /************************************************************************
 3 singleton模式類模板
 4 1:延遲創建類實例    2:double check    3:互斥訪問    4:模板
 5 ************************************************************************/
 6 #ifndef WHG_SINGLETON
 7 #define WHG_SINGLETON
 8 
 9 #include "ThreadLockCs.h"
10 
11 template<class T>
12 class CSingleton
13 {
14 private:
15     static T* _instance;
16     CSingleton(void);
17     static CThreadLockCs lcs;
18 public:
19     static T* Instance(void);
20     static void Close(void);
21 };
22 
23 //模板類static變量
24 template<class T> 
25 T*  CSingleton<T>::_instance = NULL;
26 
27 template<class T> 
28 CThreadLockCs CSingleton<T>::lcs;
29 
30 //模板類方法實現
31 template<class T>
32 CSingleton<T>::CSingleton(void)
33 {    
34 }
35 
36 template<class T>
37 T*  CSingleton<T>::Instance(void)
38 {
39     //double-check
40     //延遲創建,只有調用方訪問Instance才會創建類實例
41     if (_instance == NULL)
42     {
43         //互斥訪問鎖,用CriticalSection實現
44         lcs.lock();
45         if (_instance == NULL)
46         {
47             _instance = new T;
48         }
49         lcs.unlock();
50     }
51     return _instance;
52 }
53 
54 template<class T>
55 void CSingleton<T>::Close(void)
56 {
57     if (_instance)
58     {
59         delete _instance;
60     }
61 }
62 
63 #endif

 

CSingleton內用到的CThreadLockCs 實現如下:

 1 //互斥訪問鎖
 2 #ifndef WHG_THREAD_LOCKCS
 3 #define WHG_THREAD_LOCKCS
 4 
 5 //#include <Windows.h>
 6 
 7 class CThreadLockCs
 8 {
 9 public:
10     CThreadLockCs(){InitializeCriticalSection(&m_cs);}
11     ~CThreadLockCs(){DeleteCriticalSection(&m_cs);}
12     void lock(){EnterCriticalSection(&m_cs);}
13     void unlock(){LeaveCriticalSection(&m_cs);}
14 private:
15     CRITICAL_SECTION m_cs;
16 };
17 #endif

 

調用方法很簡單:

1:用typedef申明一個變量名

1 typedef CSingleton<CListen>    LISTEN;

 

2:調用的地方寫

1 LISTEN::Instance()->SetAddress(8828,"127.0.0.1");

 

3:關閉的地方寫

1 LISTEN::Close();

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM