C++ 单例模式

单例模式

  • 一个类仅有一个实例
  • 提供该实例的全局访问点

单线程下的单例模式:

cpp 复制代码
class Singleton{
public:
	static Singleton * GetInstance(){
		if(_instance == nullptr)
		{
			_instance = new Singleton();
			std::atexit(Destructor);
		}
		return _instance;
	}
private:
	static void Destructor(){
		if(_instance != nullptr){
			delete _instance;
			_instance = nullptr;
		}
	}
	Singleton() {}
	~Singleton() {}
	Singleton(const Singleton &clone) {}
	Singleton & operator=(const Singleton &) {};
	static Singleton *_instance;
};
Singleton *Singleton::_instance = nullptr;

1.静态成员函数和静成员变量

2.构造、析构、赋值操作符、拷贝构造私有化

3.new是堆上创建std::atexit

多线程下的单例模式:

cpp 复制代码
#include <mutex>
#include <atomic>
class Singleton{
public:
	static Singleton * GetInstance(){
		Singleton *temp = _instance.load(std::memory_order_relaxed);
		std::atomic_thread_fence(std::memory_order_acquire);//内存栅栏,确保在此点之前的所有读操作都完成,并且在此点之后的所有读操作都不会被重排到这个点之前
		//std::lock_guard<std::mutex> lock(_mutex);
		if(_instance == nullptr)
		{
			std::lock_guard<std::mutex> lock(_mutex);
			temp = _instance.load(std::memory_order_relaxed);
			if(_instance == nullptr)
			{
				temp = new Singleton();//多线程环境下编译器和cpu对程序进行优化
				std::atomic_thread_fence(std::memory_order_release);
				_instance.store(temp,std::memory_order_relaxed);
				//1.分配内存 2.调用构造函数 3.返回指针、赋值运算
				//优化为1、3、2
				std::atexit(Destructor);
			}		
		}
		return _instance;
	}
private:
	static void Destructor(){
		Singleton *temp = _instance.load(std::memory_order_relaxed);
		if(temp != nullptr){
			delete temp;
			_instance.store(temp,std::memory_order_relaxed);
			temp = nullptr;
		}
	}
	Singleton() {}
	~Singleton() {}
	Singleton(const Singleton &clone) {}
	Singleton & operator=(const Singleton &) {};
	static std::atomic<Singleton *> _instance;
	static std::mutex _mutex;
};
std::atomic<Singleton *> Singleton::_instance = nullptr;
std::mutex Singleton::_mutex;

1.两次判断,希望在第二次判断的时候加互斥锁

2.多线程环境下,编译器、cpu的优化(指令重排)------原子操作+内存屏障


获取更多Linux C/C++资料

相关推荐
滕州市燕猫虎计算机科技工作室个体工商户7 小时前
Java面试题汇总
java·开发语言
孙启超8 小时前
【AI开发之Rust】第 3 课:字符串与复合类型 —— 数据怎么放
开发语言·人工智能·后端·rust·llm·transformer
t-think8 小时前
C++ string 类(上)—— string类初识与常用接口详解
开发语言·c++
cpp_learners8 小时前
C++ 实现责任链模式(Chain of Responsibility):从一堆 if-else 到可插拔的处理管道
开发语言·c++·责任链模式
郝学胜_神的一滴9 小时前
C++11 工程级应用 12:编译期类型魔法,干掉重复与臃肿的代码
c++·visual studio
君顾19 小时前
外卖CPS软件开发实战:从系统架构到部署全流程指南
java·开发语言·外卖
AIFQuant9 小时前
Python实时外汇行情接入实战:WebSocket与REST K线查询
开发语言·python·websocket
名字还没想好☜9 小时前
Java NIO ByteBuffer 实战:flip/clear/compact 三个绕晕人的方法与 position/limit 心智模型
java·开发语言·后端·spring·nio
小溪学编程10 小时前
AQS 原理详解:从 CLH 队列到 ReentrantLock 的实现
java·开发语言