c++ - 单例模式的几种写法

1.double check (DCL)

  • 这种为比较经典的写法,程序上看起来没有什么问题,且是线程安全的,但是在现在多核cpu 架构体系下,会进行指令重排,导致程序不会按预期的方式运行
#ifndef SINGLETON_TEMPLATE_H_
#define SINGLETON_TEMPLATE_H_


#include <mutex>


//thread-safe singleton template
template <class T>
class Singleton {
public:
    static T* instance() {
        if(instance_ == NULL) {
            std::lock_guard<std::mutex> lock(mutex_create_instance_);
            if(instance_ == NULL) {    //check again for it may be changed by the other thread when the lock is released
                instance_ = new T;
            }
        }
        return instance_;
    }


    //release all the resources
    static void destroy() {
        if(instance_ != NULL) {
            delete instance_;
            instance_ = NULL;
        }
        return;
    }
protected:
    Singleton() {};
    ~Singleton() {};
    /* class uncopyable */
    Singleton(const Singleton&);
    Singleton& operator=(const Singleton&);
private:
    static T* instance_;
    static std::mutex mutex_create_instance_; //make sure thread-safe singleton creation
};

2.linux 下的单例模式,相同的写法在c++ 11 中有 std::once_flag 库可以替代了,有相同的效果

template<typename T>
class Singleton
{
public:
    static T& instance()
    {
        pthread_once(&ponce_,&Singleton::init);
        return *value_;
    }
    
private:
    Singleton();
    ~Singleton();
    static void init()
    {
        value_ = new T();
    }
    
private:
    static pthread_once_t ponce_;
    static T* value_;
}


//必须在头文件中定义static 变量
template<typename T>
phread_once_t Singleton<T>::ponce_ = PTHREAD_ONCE_INIT;


template<truename T>
T* Singleton<T>::value_ = NULL;

3.使用static 包装,这种方式最简单,且是线程安全的,使用static 修饰,变量存储在静态存储区,在程序运行前就已经初始化好了

class CSingleton
{
    CSingleton() {}
    ~CSingleton() {}
    static CSingleton& getInstance()
    {
        static CSingleton m_instance;
        return m_instance;
    }
}
posted @ 2020-07-31 10:53  boht  阅读(745)  评论(0编辑  收藏  举报