模板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();

 

posted on 2016-11-21 16:31  炽离  阅读(4345)  评论(0编辑  收藏  举报

导航