首页 > 代码库 > 单例模式

单例模式

单例模式通过类本身来管理其唯一实例,这种特性提供了解决问题的方法。唯一的实例是类的一个普通对象,但设计这个类时,让它只能创建一个实例并提供对此实例的全局访问。唯一实例类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,如果按照原来的方法,每次获取实例都需要加锁,效率太低。而改进的方法只需要在第一次 调用的时候加锁,可大大提高效率。