创建型模式-----(单例模式)

目录

基本概念

饿汉式:

懒汉式:

         上锁双判空版本

std::call_once版本:

C++11标准后局部静态变量版本:

项目中单例模板的应用


基本概念

单例模式:在程序运行期间只有一份,与程序生存周期一样,因此无需手动释放内存,由程序结束后系统自动回收进程内存。
类单例的方式:

              1.构造函数私有化 禁止用户随便构造。
              2.创造属于类的私有静态实例并仅限通过静态函数访问实例;
              3.拷贝和赋值构造需要私有化或者禁掉。
              4.考虑多线程竞态可能创建多个实例等。

UML图:

饿汉式:

类加载即实例化,无线程竞争问题;但可能在实际使用前很久该单例一直未使用,空耗内存。

class EhanSingle
{
public:
	EhanSingle(const EhanSingle&) = delete;
	EhanSingle&operator = (const EhanSingle&) = delete;
	~EhanSingle() = delete;
	static EhanSingle* getInstance()
	{
		return instance;
	}
private:
	EhanSingle() = default;
	static EhanSingle *instance;

};
//类加载即实例化 无线程竞争问题
EhanSingle* EhanSingle::instance = new EhanSingle;

懒汉式:

上锁双判空版本

        只有在程序实际需要使用单例实例时,才进行初次创建,内存效率较高,但需要考虑线程竞态问题。

        该代码中使用了互斥锁+双层判空机制防止产生多个实例;同时使用原子变量防止实例在创建时候由于指令重排可能导致的实例构建失败。

//懒汉  
#include<atomic>
#include<mutex>
class LanHanSignle
{
public:
	LanHanSignle(const LanHanSignle&) = delete;
	LanHanSignle& operator = (const LanHanSignle&) = delete;
	~LanHanSignle() = delete;
	static LanHanSignle*getInstance()
	{
		LanHanSignle *instance = atom_instance.load();
		if (instance == nullptr)
		{
			mtx.lock(); //上锁 双层判空防止多线程产生多个
			if (instance == nullptr)
			{
				//atomic存储操作是为了防止指令重排序 
				//1分配内存 2 在内存构建实例 3 指针指向内存
				//重排后可能1,3,2 当2出错后指针指向内存为空但是实例构造失败
				instance = new (std::nothrow) LanHanSignle();
				atom_instance.store(instance);
			}
			mtx.unlock();
		}
		return instance;
	}
private:
	LanHanSignle();
	static std::mutex mtx;
	static std::atomic<LanHanSignle*> atom_instance;
};

std::call_once版本:

        对于只执行一次构造可以采用std::call_once进行延迟实例构造,而且可以避免懒汉需要上锁的问题;但同时也存在一次构造失败会导致后续不会重新构造实例问题

class LanHanSingleton
{
public:
	LanHanSingleton(const LanHanSingleton&) = delete;
	LanHanSingleton& operator = (const LanHanSingleton&) = delete;
	static LanHanSingleton* getInstance()
	{
		//如果第一次构造失败后续会一直返回错误的instance 
		std::call_once(once_flag, LanHanSingleton::createInstance);
		return instance;
	}
private:
	static LanHanSingleton* instance;
	static std::once_flag once_flag;
	static void createInstance() { instance = new(std::nothrow) LanHanSingleton; }
	LanHanSingleton() = default;
	~LanHanSingleton() = default;
};

LanHanSingleton* LanHanSingleton::instance = nullptr;
std::once_flag LanHanSingleton::once_flag;

C++11标准后局部静态变量版本:

        c++11 标准保证指令逻辑进入未被初始化的静态变量,所有并发操作应该等待变量初始化完成;由此可以简化懒汉的线程竞态产生的问题。

//静态局部变量 简化懒汉式
class LanHanSingleStaticLocal
{
public:
	LanHanSingleStaticLocal(const LanHanSingleStaticLocal&) = delete;
	LanHanSingleStaticLocal& operator = (const LanHanSingleStaticLocal&) = delete;
	static LanHanSingleStaticLocal* getInstance()
	{
		//c++11 标准保证指令逻辑进入未被初始化的声明变量 
		//所有并发操作应该等待变量初始化完成
		static LanHanSingleStaticLocal instance;
		return&instance;
	}
private:
	LanHanSingleStaticLocal() = default;
	//不能=delete 局部静态变量退出需要调用
	~LanHanSingleStaticLocal() = default;
};

项目中单例模板的应用

        在项目中一般会有许多全局唯一的变量,如软件的配置文件、数据缓存、数据库的连接池、枚举映射、计费单元、用户单元等等;可以使用单例模板对这些类进行简化编写。

如采用局部静态变量的单例模板如下:

template<typename T>
class Singleton
{
public:
	Singleton(const Singleton&) = delete;
	Singleton& operator = (const Singleton&) = delete;
	static T* getInstance()
	{
		static T instance;
		return&instance;
	}
private:
	Singleton() = default;
	~Singleton() = default;
};

新建一个单例缓存类如下:

#pragma once
#include<string>
#include<map>
#include "Signleton.h"
using namespace std;

//宏便于后续使用
#define g_DataCache  Singleton<CacheHelper>::getInstance()
class CacheHelper
{
    //声明友元 便于单例调用该类私有构造函数
	friend Singleton<CacheHelper>;
public:
	string getValue(const string&key) const;
	void setValue(const string&key, const string&value);
	/*
	...
	*/
private:
	CacheHelper() {}
	~CacheHelper() {};
	std::map<string, string>m_CacheMap;
	/*
	...
	*/
};

使用单例

g_DataCache->setValue("CameraSerialNo","DTS-TP303");
string cameraSerialStr = g_DataCache->getValue("CameraSerialNo");

线程池中的应用:

#define g_Get_EtcThreadPool Singleton<EtcThreadPool>::getInstance()

class EtcThreadPool 
{
public:
	friend Singleton<EtcThreadPool>;
	QThreadPool *GetEtcThreadPool();
	void DestoryThreadPool();
private:
	EtcThreadPool() = default;
	~EtcThreadPool() = default;
	QMutex m_EtcPoolMutex;
	QThreadPool *m_EtcThreadPool = nullptr;
	void InitEtcThreadPool();
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/898606.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

记一行代码顺序引起的事故

01 前情回顾 在这里跟同学们分享一个前几天在线上遇见的 bug… bug描述&#xff1a;客户端轮询服务端接口获取数据做打字机效果展示&#xff0c;会偶现输出到一半就停止不动了&#xff0c;但是数据还没输出完&#xff08;如下图&#xff0c;到红色部分就卡住了&#xff09;。…

【Axure高保真原型】移动案例

今天和大家分享多个常用的移动案例的原型模板&#xff0c;包括轮盘滑动控制元件移动、页面按钮控制元件移动、鼠标单击控制元件移动、元件跟随鼠标移动、鼠标拖动控制元件移动、键盘方向键控制元件移动&#xff0c;具体效果可以点击下方视频观看或打开下方预览地址查看哦 【原…

虚拟装配解决方案:在虚拟现实中实现移动零件与三维模型碰撞检测

装配过程占产品开发时间和成本的很大一部分。在投入生产前对产品装配进行碰撞检测能够有效的降低因设计疏忽所导致的重复试错所导致的成本增加&#xff0c;并进一步降低设计审核整体流程所需时间。 选择、移动和操作3D模型的各个部分 TechViz多通道软件具有通用零件识别引擎&am…

Core webapi<1>特性 Route、Bind、HttpGet、Consumes、Produces

微软资料 Consumes Produces 让 API 返回 text/json 类型的数据。因为默认情况下&#xff0c;API 返回数据使用 application/json 格式&#xff0c;所以&#xff0c;咱们要改为 text/json&#xff0c;就得用 Produces 特性。

Java最全面试题->Java基础面试题->JavaEE面试题->Web应用服务器面试题

文章目录 Web应用服务器面试题Tomcat是什么?Tomcat缺省端口是多少&#xff0c;如何修改&#xff1f;Tomcat 有那几种Connector 运行模式&#xff1f;什么是Servlet&#xff1f;Servlet请求过程&#xff1f;Tomcat执行流程&#xff1f;Tomcat部署方式?什么是JBoss ?在JBoss 7…

UG NX12.0建模入门笔记:1.1 UG界面编辑

文章目录 一、用户默认设置&#xff1a;修改新建零件时的默认存储路径。二、用户默认设置&#xff1a;修改默认图纸的尺寸单位。三、如何移除不需要的工具栏&#xff1f;四、如何将角色设置成高级&#xff0c;以使用更多的功能&#xff1f;五、如何修改软件背景颜色&#xff1f…

w~自动驾驶合集9

我自己的原文哦~ https://blog.51cto.com/whaosoft/12320882 #自动驾驶数据集全面调研 自动驾驶技术在硬件和深度学习方法的最新进展中迅速发展&#xff0c;并展现出令人期待的性能。高质量的数据集对于开发可靠的自动驾驶算法至关重要。先前的数据集调研试图回顾这些数据集&…

取得六西格玛绿带培训证书有什么用?

六西格玛作为一套科学的管理方法和工具&#xff0c;已被广泛应用于各个行业。而六西格玛绿带培训证书&#xff0c;作为这一体系中的基础认证&#xff0c;不仅是对个人专业能力的认可&#xff0c;更是职业生涯中的一大助力。本文&#xff0c;天行健企业管理咨询公司旨在分享取得…

山东济南杰出思想家颜廷利:升命学说,当今世界前沿哲学思想

颜廷利教授的"升命学说"是一个将现代科技发展与中华传统文化相结合的当今世界前沿哲学教育理论框架&#xff0c;它是在传统哲学基础上的一种目前社会创新性思想体系。为了理解"升命学说"与传统哲学的不同之处&#xff0c;我们可以从以下几个方面来探讨&…

通过docker desktop拉取镜像打包镜像传输到其它服务器中

通过docker desktop拉取镜像打包镜像传输到其它服务器中 使用 docker save 命令将镜像保存为 tar 文件 docker save -o <path-for-tar-file> <image-name-with-tag>例如&#xff0c;如果想要保存名为 myimage:latest 的镜像&#xff0c;并将其保存到当前目录的 m…

【K8S系列】Kubernetes node节点NotReady问题及解决方案详解【已解决】

Kubernetes 集群中的每个节点都是运行容器化应用的基础。当节点状态显示为 NotReady 时,意味着该节点无法正常工作,这可能会导致 Pod 无法调度,从而影响整个应用的可用性。本文将深入分析节点不健康的各种原因、详细的排查步骤以及有效的解决方案。 一、节点不健康的原因 节…

Leetcode—1226. 哲学家进餐【中等】(多线程)

2024每日刷题&#xff08;185&#xff09; Leetcode—1226. 哲学家进餐 C实现代码 class DiningPhilosophers { public:mutex mx;DiningPhilosophers() {}void wantsToEat(int philosopher,function<void()> pickLeftFork,function<void()> pickRightFork,functi…

双十一开启极速达夜派;黑神话获泰国年度最佳游戏;AI 模型可帮助识别 17000 多种疾病的候选药物....| 网易数智日报

双 11 菜鸟在北京、上海、广州、杭州等城市开启「预售极速达夜派」服务 10 月 21 日&#xff0c;菜鸟在北京、上海、广州、杭州等城市开启「预售极速达夜派」服务&#xff0c;批量大促包裹实现小时级送达。 据介绍&#xff0c;在消费者支付尾款前&#xff0c;菜鸟供应链就已经…

闯关leetcode——190. Reverse Bits

大纲 题目地址内容 解题代码地址 题目 地址 https://leetcode.com/problems/reverse-bits/description/ 内容 Reverse bits of a given 32 bits unsigned integer. Note: Note that in some languages, such as Java, there is no unsigned integer type. In this case, …

使用excel.js(layui-excel)进行layui多级表头导出,根据单元格内容设置背景颜色,并将导出函数添加到toolbar

本段是菜狗子的碎碎念&#xff0c;解决办法请直接从第二段开始看。layui多级表头的导出&#xff0c;弄了两天才搞定&#xff0c;中途一度想放弃&#xff0c;还好坚持下来了。一开始用的是layui的toolbar里自带的那个导出&#xff0c;但是多级表头没有正常导出&#xff0c;单元格…

ORACLE SELECT INTO 赋值为空,抛出 NO DATA FOUND 异常

例子&#xff1a; DECLARE ORDER_NUM VARCHAR2(20); BEGIN SELECT S.ORDER_NUM INTO ORDER_NUM FROM SALES_ORDER S WHERE S.ID122344; DBMS_OUTPUT.PUT_LINE(单号: || ORDER_NUM); END; 在查询结果为空的情况下&#xff0c;以上代码会报错&#xff1a;未找到任何数据 解决方…

深度学习——循环神经网络RNN知识点小结(全)

前置知识: 序列模型--输出/输入中包含有序列数据的模型 特点: 1.输入/输出元素之间具有顺序关系, 不同顺序得到的结果不同 2.输入输出不定长, 比如问答系统, 聊天机器人 DL--RNN 小名:循环神经网络 外国小名: sequence model 定义: 专门设计用来处理序列数据的神经网络 应用: …

2024临床常用的营养评价量表汇总!

临床常用量表来评估患者的营养状况、营养摄入风险&#xff0c;常笑医学整理了5个临床常用的营养评价量表&#xff0c;包括SGA营养评价表、老年营养风险指数、营养风险筛查评分简表、简易营养评价精法量表、微型营养评估量表等。这些量表在常笑医学网均支持在线评估、下载和创建…

(四)问题记录:matlab中spatial contact force模块下关于stiffness(刚度)的设定

最近在搞一阶倒立摆&#xff0c;在matlab仿真时遇到这样的问题&#xff1a;stiffness设置为10e5就会发生碰撞后穿透&#xff0c;&#xff08;四个spatial contact force模块是分别连接小车四个轮子和地面的&#xff09; 而设置成10e6就不会有问题&#xff0c; 由于本人也是第一…

cefsharp 88.2.90.0(Chromium 88.0.4324.182)支持H264视频播放-PDF预览 老版本回顾系列体验-100以下版本

一、关于此版本 Cef 88.2.9/CefSharp 88.2.90/Chromium 88.0.4324.182/支持H264/支持PDF预览 支持PDF预览和H264推荐版本 63/79/84/88/100/111/125 框架:NET4.5.2,X86 注意运行环境支持变化1.1 扩展(关于DPI黑边框问题解决) this.AutoScaleMode = AutoScaleMode.Dpi;