Singleton Pattern 单例模式

       单例模式,顾名思义是确保一个类只有一个实例,并提供一个全局访问点。有一些对象我们只需要一个。例如对话框、线程池、注册表对象、日志对象等。事实上,这类对象只能有一个实例,如果制造出多个实例,就会导致出现问题。

       为了只有一个实例。有很多方法,例如声明全局变量。但是单件模式是更好的做法,是久经时间考验的方法。全局模式有固有的缺点。例如如果将一个对象赋值给一个全局变量,那么你必须在程序一开始就创建好对象,万一这个对象非常耗费资源,而程序在这次执行过程中又一直没有用到它,不就形成了浪费了吗?而单例模式,我们可以在需要时才创建对象。


经典的单例模式实现:


class Singleton{
private:
    Singleton(){
        //构造函数是私有的,只有类内才能访问构造函数
    }
    static Singleton* uniqueInstance;  //用一个静态变量来记录Singleton类的唯一实例
public:
    static Singleton* getInstance()
    {
     if(uniqueInstance==NULL){
        uniqueInstance=new Singleton();
     }
     return uniqueInstance;
    }

};
   用户获取实例的方法只能调用getInstance方法,其他任何尝试都会失败,因为构造方法是私有的。


   对于多线程调用,以上代码是不安全的,依然有可能会出现生成多个实例。主要原因是因为在getInstance()方法并非同步的或者加锁的,不具有原子性,可能被多线程穿插调用。那么考虑到线程安全可以做一下改进:

//考虑到线程安全
class Lock{
private:
    CCriticalSection m_cs; //临界区
public:
    Lock(CCriticalSection cs):m_cs(cs)
    {
        m_cs.Lock();    
    }
    ~Lock(){
        m_cs.Unlock();
    }
};


class Singleton_safe{
private:
    Singleton_safe(){}
    static Singleton_safe *UniqueSingleton;
    static CCriticalSection cs;
public:
    static Singleton_safe* getInstance(){
        if(UniqueSingleton==NULL){
            Lock(cs);
            if(UniqueSingleton==NULL){
                UniqueSingleton=new Singleton_safe();
            }
        }
    }
};

      其中,判断UniqueSingleton是否为空用了两次,主要是因为大多数(除1次以外)UniqueSingleton不为NULL。所以,加锁只有一次会调用,避免了每次判断都加锁,大大的降低了加锁开销。


学习:http://blog.csdn.net/hackbuteer1/article/details/7460019

你可能感兴趣的:(Singleton Pattern 单例模式)