C++ 单例模式(介绍+实现)

文章目录

  • 一. 设计模式
  • 二. 单例模式
  • 三. 饿汉模式
  • 四. 懒汉模式
  • 结束语

一. 设计模式

单例模式是一种设计模式
设计模式(Design Pattern)是一套被反复使用,多数人知晓的,经过分类的,代码设计经验的总结

为什么要有设计模式

就像人类历史发展会产生兵法,最开始部落之间打仗都是谁人多谁获胜。但后来春秋战国时期,七国之间经常战争,发现战争也是有套路的,后来孙子就总结了《孙子兵法》。设计模式也是如此。

设计模式可以提高代码的可重用性,让代码更容易被他人理解,保证代码可靠性。设计模式使代码编写真正工程化;设计模式是软件工程的基石脉络,如同大厦的结构一般

二. 单例模式

一个类只能创建一个对象,即单例模式,该模式可以保证系统重该类只有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享

比如在某个服务器程序中,该服务器的配置信息存放在一个文件中,这些配置数据由一个单例对象统一读取,然后服务进程中的其他对象再通过这个单例对象获取这些配置信息,这种方式简化了在复杂环境下的配置管理

单例模式有两种实现方式:饿汉模式&懒汉模式

三. 饿汉模式

饿汉模式,是在最开始就创建对象,即main函数开始前,对象就已经存在

要点有以下几个:

  1. 因为全局只能有一个对象,所以需要将构造函数私有化
  2. 内部封装static静态对象指针,然后类外初始化
  3. 提供静态成员函数,返回静态对象指针
  4. 使用互斥锁保证数据读取的线程安全
//饿汉模式
//在main函数调用前对象就存在
class Singleton
{
public://静态成员变量获取对象指针static Singleton*GetInstance(){return _ins;}//添加数据void Add(const char*str){_vmtx.lock();_v.push_back(str);_vmtx.unlock();}//打印数据void Print(){_vmtx.lock();for (auto& e : _v){cout << e << endl;}_vmtx.unlock();}private://构造函数私有化Singleton(){}
private:vector<string> _v;//存储数据mutex _vmtx;//互斥锁static Singleton*_ins;//静态指针
};//静态成员变量类外初始化
Singleton* Singleton::_ins = new Singleton();

饿汉模式的优点就是相对于懒汉模式,较为简单
缺点是,程序刚开始时就创建,如果对象较大,可能导致进程启动慢,且如果有多个单例类对象实例启动顺序不确定

如果这个单例对象在多线程并发环境下频繁使用,性能要求较高,那么显然使用饿汉模式来避免资源竞争,提高响应速度更好

四. 懒汉模式

懒汉模式是在第一次使用实例对象时,才创建对象

如果单例对象构造十分耗时或者占用很多资源,比如加载插件,初始化网络连接,读取文件等,为了不影响程序启动,可以使用懒汉模式(延迟加载

简易的懒汉模式

class Singleton
{
public://静态成员变量获取对象指针static Singleton*GetInstance(){static Singleton _ins;return &_ins;}//添加数据void Add(const char*str){_vmtx.lock();_v.push_back(str);_vmtx.unlock();}//打印数据void Print(){_vmtx.lock();for (auto& e : _v){cout << e << endl;}_vmtx.unlock();}private://构造函数私有化Singleton(){}
private:vector<string> _v;//存储数据mutex _vmtx;//互斥锁
};

stactic对象在C++11前无法保证线程安全,C++11后保证static对象初始化时线程安全的


复杂的懒汉模式

要点有如下几个:

  1. 懒汉模式的GetInstance需要有双检查加锁,同时因为是静态成员函数,所以还需要封装一个静态的互斥锁保护
  2. 可以使用DelInstance显示释放,但也可以通过回收机制在程序结束时回收资源。
    做法是内部定义一个类,该类的析构函数会显示调用DelInstance,然后再定义一个全局的回收机制对象,这样程序结束时会自动销毁回收机制对象,同时调用DelInstance
//懒汉模式
//第一次调用GetInstance才有对象
class Singleton
{
public://静态成员变量获取对象指针static Singleton*GetInstance(){//双检查加锁if (_ins == nullptr)//提高效率{_imtx.lock();//第一次调用为空才初始化if (_ins == nullptr)//线程安全{_ins = new Singleton();}_imtx.unlock();}return _ins;}//添加数据void Add(const char*str){_vmtx.lock();_v.push_back(str);_vmtx.unlock();}//打印数据void Print(){_vmtx.lock();for (auto& e : _v){cout << e << endl;}_vmtx.unlock();}//销毁static void DelInstance(){_imtx.lock();if (_ins){delete _ins;_ins = nullptr;}_imtx.unlock();}//回收机制class GC{public:~GC(){DelInstance();}};static GC _gc;//声明
private://构造函数私有化Singleton(){}
private:vector<string> _v;//存储数据mutex _vmtx;//保护vector的互斥锁static Singleton*_ins;//静态指针static mutex _imtx;//保护Singleton初始化的互斥锁
};//静态成员变量类外初始化为空
Singleton* Singleton::_ins = nullptr;
mutex Singleton::_imtx;//程序结束时,会调用其析构函数,内部再调用DelInstance()
Singleton::GC Singleton::_gc;//定义

结束语

感谢你的阅读

如果觉得本篇文章对你有所帮助的话,不妨点个赞支持一下博主,拜托啦,这对我真的很重要。
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

WEB:wife_wife

背景知识 JavaScript原型链污染 题目 先尝试一下&#xff0c;注册了管理员账号 这里不知道邀请码&#xff0c;所以没有勾选 答案不正确 这里借鉴其他大佬的思路 查看源代码才知道&#xff0c;后端没有数据库&#xff0c;所以sql注入是不可能的 // post请求的路径 app.pos…

【网络】应用层——协议定制 | 序列化和反序列化 | 初识http

&#x1f431;作者&#xff1a;一只大喵咪1201 &#x1f431;专栏&#xff1a;《网络》 &#x1f525;格言&#xff1a;你只管努力&#xff0c;剩下的交给时间&#xff01; 在前面本喵已经带大家见识过了scoket网络通信的样子&#xff0c;现在开始深入学习网络的原理&#xff…

机器学习 day29(高偏差、高方差,参数d对模型的影响)

1. 高偏差、高方差、拟合能力、泛化能力 偏差和方差分别代表拟合能力和泛化能力若给左图数据集拟合一阶多项式&#xff08;d取1&#xff09;&#xff0c;则该模型有很高的偏差&#xff08;欠拟合&#xff09;。因为它对训练集和验证集的表现均不好&#xff0c;所以Jtrain很高…

快手内推(2024校招,社招)

校招 校招可以直接投递&#xff0c;如果想投递指定部门或岗位的可以私聊我。可以帮看简历和面试状态&#xff0c;加快推进。 内推码&#xff1a;vlxMTFNBS 专属内推链接&#xff1a;https://campus.kuaishou.cn/#/campus/jobs?codevlxMTFNBS 社招 社招内推私聊&#xff0c;可…

[Java]详解什么是注解以及如何自定义注解?

文章目录 一、什么是注解(1).注解的作用(2).注解的格式(3).注解在哪里使用 二、注解的类型(1).内置注解(2).元注解(3).自定义注解 三、自定义注解实现及测试结果&#xff1a; 一、什么是注解 (1).注解的作用 ①&#xff1a;注解一般用于对程序的说明&#xff0c;就像注释一样…

windows系统修改mysql8配置文件,关闭ssl验证

如何寻找配置文件 我的电脑&#xff0c;右键&#xff0c;管理&#xff0c;服务 找到MySQL8 右键&#xff0c;属性 找到配置文件位置 通常情况下的默认路径是&#xff1a; C:\ProgramData\MySQL\MySQL Server 8.0\my.ini 如何关闭SSL验证 打开 my.ini 配置内容如下&#x…

【100天精通python】Day7:数据结构_列表 List的创建、删除、访问、遍历、统计、排序、推导等使用

目录 1 列表的创建 2 列表的删除 3 访问列表元素 4 遍历列表 5 添加修改删除列表元素 6 对列表进行统计和计算 7 对列表进行排序 8 列表推导式 9 多维列表 在Python中&#xff0c;列表是一种有序的可变数据类型&#xff0c;用于存储一组元素。 列表使用方括号“[] ”来…

Qt5.14.2下载及安装

1. 下载 https://download.qt.io/archive/qt/5.14/5.14.2/ 由于Qt 自从5.15版本开始&#xff0c;对非商业版本&#xff08;也就是开源版本&#xff09;&#xff0c;不提供已经制作好的离线exe安装包。所以&#xff0c;对于5.15&#xff08;含&#xff09;之后的版本&#xff…

Idea 设置类和方法的注释(获取参数)

Idea 添加注释&#xff1a;类注释、方法注释 类注释 方法注释 类注释 File–Setting–Editor–File and Code Templates–Class: 注释模板&#xff1a; /** **description: *author: fqtang*time: ${DATE} ${TIME}* */ 操作截图&#xff1a; 效果&#xff1a; 方法注释 为了…

图数据库Neo4j学习二——cypher基本语法

1命名规范 名称应以字母字符开头&#xff0c;不以数字开头&#xff0c;名称不应包含符号&#xff0c;下划线除外可以很长&#xff0c;最多65535( 2^16 - 1) 或65534字符&#xff0c;具体取决于 Neo4j 的版本名称区分大小写。:PERSON和:Person是:person三个不同的标签&#xff…

Jmeter+Jenkins+Ant自动化持续集成环境搭建

一、安装准备 1.JDK:jdk-8u121-windows-x64 2.jmeter工具&#xff1a;apache-jmeter-2.13 3.ANT工具&#xff1a;apache-ant-1.9.7-bin 4.jenkins工具&#xff1a;jenkins-2.32.2 二、软件安装 1.JDK的安装 >双击JDK安装包&#xff0c;选择安装路径&#xff08;本人是…

详细总结Webpack5的配置和使用

打包工具 使用框架&#xff08;React、Vue&#xff09;&#xff0c;ES6 模块化语法&#xff0c;Less/Sass 等 CSS预处理器等语法进行开发的代码要想在浏览器运行必须经过编译成浏览器能识别的 JS、CSS 等语法&#xff0c;才能运行。 所以需要打包工具帮我们做完这些事。除此之…

3、C# 方法构成

上一节,我们讲述了程序的基本构成。由大到小分别为”解决方案-->项目-->类-->方法“。 这一节,我们讲讲方法。 方法可以说是程序的基本构成单位。假如把方法抽象成点的话,我们可以认为程序是一个树状的结构。树根,就是我们的起点方法,也叫主方法。这一点,基本…

决策树(Decision Tree)

决策树的原理 决策树算法是一种基于树结构的分类和回归算法。它通过对数据集进行递归地分割&#xff0c;构建一个树形模型&#xff0c;用于预测目标变量的值。 决策树的构建过程基于以下原理&#xff1a; 1. 特征选择&#xff1a;选择最佳的特征来进行数据集的分割。常用的…

堆排序与直接选择排序

目录 一、直接选择排序 1.基本思想 2.直接选择排序的特性总结 3.代码实现&#xff1a; 二、堆排序 1. 概念&#xff1a; 2.图像实现&#xff1a; 3.代码实现&#xff1a; 一、直接选择排序 1.基本思想 每一次从待排序的数据元素中选出最小&#xff08;或最大&#xff09…

MySQL多表连接查询练习

准备工作 创建student表 CREATE TABLE student ( id INT(10) NOT NULL UNIQUE PRIMARY KEY , name VARCHAR(20) NOT NULL , sex VARCHAR(4) , birth YEAR, department VARCHAR(20) , address VARCHAR(50) );创建score表 CREATE TABLE score ( id INT(10) NOT …

NetSuite ERP顾问的进阶之路

目录 1.修养篇 1.1“道”是什么&#xff1f;“器”是什么&#xff1f; 1.2 读书这件事儿 1.3 十年计划的力量 1.3.1 一日三省 1.3.2 顾问损益表 1.3.3 阶段课题 2.行为篇 2.1协作 2.2交流 2.3文档管理 2.4时间管理 3.成长篇 3.1概念能力 3.1.1顾问的知识结构 …

大数据学习05-Kafka分布式集群部署

系统环境&#xff1a;centos7 软件版本&#xff1a;jdk1.8、zookeeper3.4.8、hadoop2.8.5 本次实验使用版本 kafka_2.12-3.0.0 一、安装 Kafka官网 将安装包上传至linux服务器上 解压 tar -zxvf kafka_2.12-3.0.0.tgz -C /home/local/移动目录至kafka mv kafka_2.12-3.0…

护城河理论

护城河理论 护城河理论|来自股神巴菲特&#xff0c;是指投资的企业在某一方面的核心竞争力。 模型介绍 在2000年的伯克希尔哈撒韦的年会上&#xff0c;巴菲特说&#xff1a;让我们来把护城河作为一个伟大企业的首要标准&#xff0c;保持它的宽度&#xff0c;保持它不被跨越。我…

听GPT 讲K8s源代码--pkg(五)

在 Kubernetes 中&#xff0c;kubelet 是运行在每个节点上的主要组件之一&#xff0c;它负责管理节点上的容器&#xff0c;并与 Kubernetes 控制平面交互以确保容器在集群中按照期望的方式运行。kubelet 的代码位于 Kubernetes 代码库的 pkg/kubelet 目录下。 pkg/kubelet 目录…