设计模式-单例模式

单例模式:存在一种特殊的类,保证在系统中只存在一个实例,以此确保程序的逻辑正确性、良好的效率。

#include <iostream>
using namespace std;

class Singleton{
private:
	Singleton(){}//定义构造函数在private中,防止生成合成的默认构造函数
	Singleton(const Singleton&);//定义拷贝构造函数在private中,目的与上述一致,防止类外使用合成的拷贝函数使实例化
public:
	static Singleton* getInstance();
	static Singleton* m_instance;
};
Singleton* Singleton::m_instance=nullptr;

//单线程下实现单例模式,比较高效,但是如果在多线程下,会出错,会有线程同时进入25行代码,导致产生多个实例
Singleton* Singleton::getInstance(){
	if(m_instance==nullptr){
		m_instance=new Singleton();
	}
	return m_instance;
}

//多线程下安全的实现单例模式,但是会降低效率,因为可能m_instance不为空,但也只能通过锁只能一个线程访问
Singleton* Singleton::getInstance(){
	lock lock;//加锁,使多线程下安全使用单例模式
	if(m_instance==nullptr){
		m_instance=new Singleton();
	}
	return m_instance;
}

//双检查锁,但由于内存读写reorder(编译器优化过程)不安全
//编译器优化过程:本来第46行大致步骤为1开辟内存,2调用Singleton构造函数对内存处理,3将内存地址给m_instance;但编译器优化可能导致执行步骤为132导致错误
Singleton* Singleton::getInstance(){
	if(m_instance==nullptr){
		lock lock;
		if(m_instance==nullptr){//这个检查有必要,因为如果m_instance如果为空,多个线程在42准备进锁,如果不再次检查,多个线程会不断进锁并不断创建实例
			m_instance=new Singleton();
		}
	}
	return m_instance;
}

//C++11之后机制
std::atomic<Singleton*> Singleton::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_acqurire);//获取内存fence,不让编译器reorder
	if(tmp==nullptr){
		std::lock_guard<std::mutex>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);//释放内存fence
			m_instance.store(tmp,std::memory_order_relaxed);
		}
	}
	return tmp;
}

模式定义:保证一个类只有一个实例,并提供一个该实例的全局访问点

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值