C++ 单例模式学习(Singleton)
最近在学习设计模式,学到单例模式,觉得这一讲讲的挺好的,整理一下,一起学习学习。单例模式可能大家都已经非常熟悉了。
class Singleton{private:// 防止外部构造。Singleton() = default;// 防止拷贝和赋值。Singleton& operator=(const Singleton&) = delete;Singleton(const Singleton& singleton2) = delete;public:static Singleton* getInstance();static Singleton* m_instance;};Singleton* Singleton::m_instance=nullptr;//线程非安全版本Singleton* Singleton::getInstance() {if (m_instance == nullptr) {m_instance = new Singleton();}return m_instance;}
很明显上面这种方法存在线程安全稳定,那么通常会想到用锁,比如:
//线程安全版本,但锁的代价过高Singleton* Singleton::getInstance() {Lock lock;if (m_instance == nullptr) {m_instance = new Singleton();}return m_instance;}
//双检查锁,但由于内存读写reorder不安全Singleton* Singleton::getInstance() {if(m_instance==nullptr){Lock lock;if (m_instance == nullptr) {m_instance = new Singleton();}}return m_instance;}
instance_ = new Singleton;
if (instance_ == nullptr) { \\ 语句1std::lock_guard lock(mutex_);if (instance_ == nullptr) {instance_ = new Singleton; \\ 语句2}}
//C++ 11版本之后的跨平台实现 (volatile)std::atomicSingleton::m_instance;std::mutex Singleton::m_mutex;Singleton* Singleton::getInstance() {Singleton* tmp = m_instance.load(std::memory_order_relaxed);std::atomic_thread_fence(std::memory_order_acquire);//获取内存fenceif (tmp == nullptr) {std::lock_guard lock(m_mutex);tmp = m_instance.load(std::memory_order_relaxed);if (tmp == nullptr) {tmp = new Singleton;std::atomic_thread_fence(std::memory_order_release);//释放内存fencem_instance.store(tmp, std::memory_order_relaxed);}}return tmp;}
class Singleton {public:static Singleton& GetInstance() {static std::once_flag s_flag;std::call_once(s_flag, [&]() {instance_.reset(new Singleton);});return *instance_;}~Singleton() = default;private:Singleton() = default;Singleton(const Singleton&) = delete;Singleton& operator=(const Singleton&) = delete;private:static std::unique_ptr<Singleton> instance_;};std::unique_ptr<Singleton> Singleton::instance_;int main() {Singleton& s1 = Singleton::GetInstance();Singleton& s2 = Singleton::GetInstance();return 0;}
