单例模式 模板类实现详解

单例模式(Singleton Pattern)属于创建型模式。保证一个类仅有一个实例,并提供一个访问它的全局访问点。

  • 懒汉式:在需要用到实例时才创建实例,普通懒汉式不支持多线程,加锁的懒汉式效率比较低
  • 饿汉式:类加载时就创建实例,在没使用到实例时会浪费内存

下面是一份单例模式的模板类代码,通过atomic实现线程安全的懒汉式单例

template <class T>
class Singleton : public NonCopyable{
    
       //不可复制构造
private:
    static T *s_singleton;            //储存实例的指针
    static std::atomic_flag s_instantiated;  //是否已实例化,原子布尔,保证多线程安全
    static volatile bool s_instantiating;    //是否正在实例化中,volatile多变的

public:
    static T* instance(){
    
     //懒汉式
        if (!s_instantiated.test_and_set()){
    
      //test_and_set 设置flag为true,返回值是设置之前的flag值
            s_singleton = new T();    //构造对象
            s_instantiating = false;   //实例创建完成
        }
        while (s_instantiating);
        return s_singleton;
    }

    template <typename ...P>
    static T* instance(P... args){
    
    
        if (!s_instantiated.test_and_set()){
    
    
            s_singleton = new T(args...);
            s_instantiating = false;
        }
        while (s_instantiating);
        return s_singleton;
    }
};

template<typename T>
T* Singleton<T>::s_singleton = nullptr;

template<typename T>
std::atomic_flag Singleton<T>::s_instantiated = ATOMIC_FLAG_INIT;

template<typename T>
volatile bool Singleton<T>::s_instantiating = true;

}
  • 补充问题
    在此模板中可能出现单例嵌套,导致
    s_singleton = new T();    //此处构造对象 ,在对象构造过程中再次调用了instance
    s_instantiating = false;   //实例创建完成
    
    while (s_instantiating);处循环

Guess you like

Origin blog.csdn.net/weixin_53022668/article/details/121403317