博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

单例模式

Posted on 2014-08-08 11:22  勇敢的鑫  阅读(142)  评论(0编辑  收藏  举报

单例模式通过类本身来管理其唯一实例,这种特性提供了解决问题的方法。唯一的实例是类的一个普通对象,但设计这个类时,让它只能创建一个实例并提供对此实例的全局访问。唯一实例类Singleton在静态成员函数中隐藏创建实例的操作。

01.class CSingleton  
02.{  
03.  private:  
04.      CSingleton()   //构造函数是私有的  
05.      {  
06.      }  
07.      CSingleton(const CSingleton &);  
08.      CSingleton & operator = (const CSingleton &);  
09.  public:  
10.      static CSingleton & GetInstance()  
11.      {  
12.          static CSingleton instance;   //局部静态变量  
13.          return instance;  
14.      }  
15.};  

关于Singleton(const Singleton);和 Singleton & operate = (const Singleton&);函数,需要声明成私有的,并且只声明不实现。

考虑到线程安全、异常安全,可以做以下扩展:

01.class Lock  
02.{  
03.private:         
04.    CCriticalSection m_cs;  
05.public:  
06.    Lock(CCriticalSection  cs) : m_cs(cs)  
07.    {  
08.        m_cs.Lock();  
09.    }  
10.    ~Lock()  
11.    {  
12.        m_cs.Unlock();  
13.    }  
14.};  
15.  
16.class Singleton  
17.{  
18.private:  
19.    Singleton();  
20.    Singleton(const Singleton &);  
21.    Singleton& operator = (const Singleton &);  
22.  
23.public:  
24.    static Singleton *Instantialize();  
25.    static Singleton *pInstance;  
26.    static CCriticalSection cs;  
27.};  
28.  
29.Singleton* Singleton::pInstance = 0;  
30.  
31.Singleton* Singleton::Instantialize()  
32.{  
33.    if(pInstance == NULL)  
34.    {   //double check  
35.        Lock lock(cs);           //用lock实现线程安全,用资源管理类,实现异常安全  
36.        //使用资源管理类,在抛出异常的时候,资源管理类对象会被析构,析构总是发生的无论是因为异常抛出还是语句块结束。  
37.        if(pInstance == NULL)  
38.        {  
39.            pInstance = new Singleton();  
40.        }  
41.    }  
42.    return pInstance;  
43.}  

之所以在Instantialize函数里面对pInstance 是否为空做了两次判断,因为该方法调用一次就产生了对象,pInstance == NULL 大部分情况下都为false,如果按照原来的方法,每次获取实例都需要加锁,效率太低。而改进的方法只需要在第一次 调用的时候加锁,可大大提高效率。