1设计模式——单例模式

设计模式——单例模式

  • 单例模式代码详细

单例模式代码详细

单例的几种模式细致详解,见单例

涉及的单例指针,何时释放空间的问题,下面代码也给出答案。

这里给出模板的单例代码,使用的是双检查锁

#ifndef SINGLETON_H   //判断是否有这个头文件加进来了,有的话就增加,没有的话,跳过。
#define SINGLETON_H

#include 

//单例模板类
template <class T>
class Singleton
{
public:
    static T* getInstance()
    {
   		//这里用于初始化,从而能够在程序结束的时候,直接析构
   		//巧妙利用garbo类
        m_garbo.init();

        //判断是否第一次调用
        if (m_pInstance == nullptr)
        {
       		//这里双检查锁,为了更好的高并发功能,是懒汉实现
       		//外面if检查是否创建,没有则加锁创建
       		//其它线程同样可以加锁创建,但是加了锁后,只要执行了锁里面的内容,
       		//单例的指针就一定会被创建。当其它线程进入锁后,要么没创建,就自己创建;要么已经建好,就直接退出。
       		//从而可以高并发,但是这个也有缺陷。
            m_locker.lock();
            if (m_pInstance == nullptr)
            {
                m_pInstance = new T();
            }
            m_locker.unlock();
        }
        return m_pInstance;
    }

protected:
    //使继承者无法public构造函数和析构函数
    //单例唯一,就不pubulic构造了;但是有继承,故而protected
    Singleton() {}
    ~Singleton() {}

private:
    //禁止拷贝构造和赋值运算符. The only way is getInstance()
    //const Singleton& src  常引用对象,不改变值,但还使用引用,因为引用来的更快
    //值传递更慢
    Singleton(const Singleton& src) = delete;
    Singleton &operator=(const Singleton& src) = delete;

    //它的唯一工作就是在析构函数中析构Singleton的实例,所以private
    class Garbo
    {
    public:
        ~Garbo()
        {
        	//这里析构单例指针
            if (Singleton::m_pInstance)
            {
                delete Singleton::m_pInstance;
                Singleton::m_pInstance = nullptr;
            }
        }

        void init()
        {
        }
    };

private:
    static std::mutex m_locker;
    static T* m_pInstance;
    static Garbo m_garbo;//类的静态成员变量,类内声明,但是类外需要定义,这里由于是用来析构单例的,所以需要类外定义
    					 //但是,这个变量没有实际意义,也就是说我们业务不需要,所以设置为私有。
};

template <typename T>
std::mutex Singleton<T>::m_locker;

template <class T>
T* Singleton<T>::m_pInstance = nullptr;

template <class T>
typename Singleton<T>::Garbo Singleton<T>::m_garbo;   //这里是类外的定义,分配的是栈空间,最后程序结束,操作系统会回收它,从而带动单例析构,释放空间。

#endif // SINGLETON_H

你可能感兴趣的:(设计模式,单例模式,设计模式)