【设计模式:单例模式】

单例模式的特点:

  1. 单例类只允许一个实例
  2. 单例类必须自己创造自己的唯一实例
  3. 单例类必须给所有其他对象提供这一实例

单例模式底层如何实现:

  • 私有化构造函数,类外部无法创造类对象,实现了单例类只允许有一个实例对象的特点
  • 类定义中含有该类的唯一静态私有对象,静态变量储存再全局存储区,并且唯一
  • 用公有的静态函数作为访问接口获取该实例 

单例模式代码(饿汉模式):

class task_queue
{public://将赋值拷贝构造以及赋值拷贝操作符删除,不允许类外访问task_queue(const task_queue& s) = delete;task_queue& operator =(const task_queue& s) = delete;static task_queue *getmber(){return member;}
private://将构造函数私有化,确保只能创建出一个实例task_queue(){cout << "默认构造" << endl;}~task_queue(){cout << "析构" << endl;}//类里对该类指针进行声明static task_queue* member;
};
task_queue* task_queue:: member = new task_queue;int main()
{task_queue* ptr = task_queue::getmber();return 0;
}

常见的两种单例模式:

饿汉模式:

在定义类时把类单例对象一并创建,创建完之后调用静态成员函数就能拿到该实例对象,代码如上

懒汉模式:

与饿汉模式相对应的就是懒汉模式,二者的区别在于单例对象的创建,懒汉模式是需要单例对象时,才会创建单例对象的实例

饿汉模式代码:

//懒汉模式
class task_queue
{public://将赋值拷贝构造以及赋值拷贝操作符删除,不允许类外访问task_queue(const task_queue& s) = delete;task_queue& operator =(const task_queue& s) = delete;static task_queue* getmber(){if (member == nullptr){member = new task_queue;}return member;}
private://将构造函数私有化,确保只能创建出一个实例task_queue(){cout << "默认构造" << endl;}~task_queue(){cout << "析构" << endl;}//类里对该类指针进行声明static task_queue* member;
};
task_queue* task_queue::member = nullptr;int main()
{task_queue* ptr = task_queue::getmber();return 0;
}

懒汉模式与饿汉模式的区别:

  • 懒汉模式相比于饿汉模式,更加节省空间,嵌入式开发考虑懒汉模式 
  • 饿汉模式在多线程的场景下没有线程安全(线程安全:多线程可以同时访问该单例对象)原因是:饿汉模式已经创建了单例对象,而懒汉模式是需要使用单例对象时才会创建,由此,当多个线程同时访问时,懒汉模式下会同时创建多个单例对象(不符合单例对象的特点,创建的实例有且只有一个),存在着线程安全问题
  • 懒汉模式存在线程安全(方法一:使用互斥锁,让多个线程依次访问单例对象。方法二:使用局部静态对象)

懒汉模式代码:

方法一:使用互斥锁

 第47行的双重If能提高程序的运行效果。

方法二:局部静态对象


 

第52行处程序的正常执行顺序:

  1. 分配内存,保存task_queue对象
  2. 在内存中构造一个 task_queue对象(初始化)
  3. 使用member指针指向分配的内存

但在实际情况中,执行的顺序很有可能会被打乱,2,3会被调换位置,这就会带来当多线程同时访问时,有可能会拿到一个里面没有存放数据的member,程序就直接挂掉了,因此使用c++11中的原子变量解决,原子变量可以控制执行的顺序

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

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

相关文章

【技术支持案例】使用S32K144+NSD8381驱动电子膨胀阀

文章目录 1. 前言2. 问题描述3. 理论分析3.1 NSD8381如何连接电机3.2 S32K144和NSD8381的软件配置 4.测试验证4.1 测试环境4.2 测试效果4.3 测试记录 1. 前言 最近有客户在使用S32K144NSD8381驱动电子膨胀阀时&#xff0c;遇到无法正常驱动电子膨胀阀的情况。因为笔者也是刚开…

c#中使用数据验证器

前言 在很多情况下&#xff0c;用户的输入不一定满足我们的设计要求&#xff0c;需要验证输入是否正确&#xff0c;传统的方案是拿到控件数据进行逻辑判定验证后&#xff0c;给用户弹窗提示。这种方法有点职责延后的感觉&#xff0c;数据视图层应该很好的处理用户的输入。使用…

如何处理selenium Webdriver中的文本框?

文本框或字段在整个网页中广泛使用,本文将介绍如何在Java中使用Selenium Webdriver处理文本框。可以有各种文本字段,我们将尝试包括其中的大多数,并执行各种操作,如清除和输入文本。 我们将使用我们的Selenium游乐场网站- testkru,与各种文本框进行交互。您也可以使用同一…

后端采用SpringBoot框架开发的:ADR药物不良反应智能监测系统源码,用于监测和收集药品在使用过程中发生的不良反应的系统

ADR药物不良反应智能监测系统是一套用于监测和收集药品在使用过程中发生的不良反应&#xff08;Adverse Drug Reaction, ADR&#xff09;的系统。该系统基于医院临床数据中心&#xff0c;运用信息技术实现药品不良反应的智能监测、报告管理、知识库查询、统计分析等功能&#x…

厚积薄发,详解 IoTeX 2.0 如何推动 DePIN 赛道迈向新台阶

背 景 DePIN 是加密货币行业的一个新兴垂直领域&#xff0c;也是本轮牛市最重要的叙事之一。DePIN 通常通过发行和分配代币来激励参与者&#xff0c;用户可以通过提供资源、维护网络、参与治理等方式获得代币奖励并产生直接的经济收益&#xff0c;从而重新洗牌财富分配方…

Java线程阻塞:原因

Java线程阻塞&#xff1a;原因 1. sleep()2. suspend() 和 resume()&#xff08;不推荐&#xff09;3. yield()4. wait() 和 notify()/notifyAll() &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 线程阻塞是一个重要的概念&#xff0c;它决…

17K star!30秒偷走你的声音,开源声音克隆工具

现在的AI发展越来越快&#xff0c;生成一段语音不是难事&#xff0c;那如果生成的是你自己的声音&#xff0c;你觉得如何&#xff1f; 今天我们分享一款开源的声音克隆工具&#xff0c;只需30秒的一般音源&#xff0c;他就可以偷走你的声音&#xff0c;它就是&#xff1a;Open…

前端开发不得不知道的那些事

文章目录 一、技能提升篇vueuseJavaScript中文网JavaScript.infoRxJsWeb安全学习书栈网码农之家 二、UI篇iconfont&#xff1a;阿里巴巴矢量图标库IconPark3dicons美叶UndrawError 404摹克 三、CSS篇You-need-to-know-cssCSS TricksAnimate.cssCSS ScanCSS Filter 四、颜色篇中…

视觉SLAM第一讲

第一讲-预备知识 SLAM是什么&#xff1f; SLAM&#xff08;Simultaneous Localization and Mapping&#xff09;是同时定位与地图构建。 它是指搭载特定传感器的主体&#xff0c;在没有环境先验信息的情况下&#xff0c;于运动过程中建立环境的模型&#xff0c;同时估计自己…

KVM虚拟机迁移

KVM虚拟机迁移 KVM虚拟机迁移&#xff0c;是将某一虚拟机上的环境和软件完全复制到另一台物理机上继续运行。KVM虚拟机迁移可以优化系统负载、重新规划KVM虚拟机布局并简化KVM虚拟机的管理维护工作。 KVM虚拟机迁移的主要应用场景如下所示。 当一台KVM宿主机的负载比较高时&am…

C++重载左移运算符

通过重载左移运算符&#xff0c;可以实现cout << p;直接输出类对象的各个属性。 其只能使用全局函数重载。 注意cout的定义如下&#xff1a; _EXPORT_STD extern "C" __PURE_APPDOMAIN_GLOBAL _CRTDATA2_IMPORT ostream cout; 也就是说我们一直用来输出的c…

公布一批脸书爬虫(facebook)IP地址,真实采集数据

一、数据来源&#xff1a; 1、这批脸书爬虫&#xff08;facebook&#xff09;IP来源于尚贤达猎头公司网站采集数据&#xff1b; ​ 2、数据采集时间段&#xff1a;2023年10月-2024年7月&#xff1b; 3、判断标准&#xff1a;主要根据用户代理是否包含“facebook”和IP核实。…

《程序猿入职必会(4) · Vue 完成 CURD 案例 》

&#x1f4e2; 大家好&#xff0c;我是 【战神刘玉栋】&#xff0c;有10多年的研发经验&#xff0c;致力于前后端技术栈的知识沉淀和传播。 &#x1f497; &#x1f33b; CSDN入驻不久&#xff0c;希望大家多多支持&#xff0c;后续会继续提升文章质量&#xff0c;绝不滥竽充数…

【C语言】指针基础知识理解【续】

1. ⼆级指针 指针变量也是变量&#xff0c;是变量就有地址&#xff0c;那指针变量的地址存放在哪⾥&#xff1f;这就是 ⼆级指针 。 1.1 引入二级指针 由于一级指针已经很熟悉&#xff0c;这里就不再赘述&#xff0c;这里我们重点探讨二级指针 下面先简单使用一个二级指针看…

视图,存储过程和触发器

目录 视图 创建视图&#xff1a; 视图的使用 查看库中所有的视图 删除视图 视图的作用&#xff1a; 存储过程&#xff1a; 为什么使用存储过程&#xff1f; 什么是存储过程&#xff1f; 存储过程的创建 创建一个最简单的存储过程 使用存储过程 删除存储过程 带参的存储…

【投标】运维服务方案(2024Word完整版)

1.项目情况 2.服务简述 2.1服务内容 2.2服务方式 2.3服务要求 2.4服务流程 2.5工作流程 2.6业务关系 2.7培训 3.资源提供 3.1项目组成员 3.2服务保障 软件资料清单列表部分文档&#xff1a; 工作安排任务书&#xff0c;可行性分析报告&#xff0c;立项申请审批表&a…

kvm虚拟化平台部署

kvm虚拟化平台部署 kvm概念简介 kvm自linux2.6版本以后就整合到内核中&#xff0c;因此可以看做是一个原生架构. kvm虚拟化架构 硬件底层提供物理层面的硬件支持 linux&#xff08;host&#xff09;&#xff0c;就相当于这个架构中的宿主机&#xff0c;上面运行了多个虚拟机。…

科普文:分布式数据一致性协议Paxos

1 什么是Paxos Paxos协议其实说的就是Paxos算法, Paxos算法是基于消息传递且具有高度容错特性的一致性算 法&#xff0c;是目前公认的解决分布式一致性问题最有效的算法之一。 Paxos由 莱斯利兰伯特(Leslie Lamport)于1998年在《The Part-Time Parliament》论文中首次公 开&…

装饰大师——装饰模式(Java实现)

引言 大家好&#xff0c;上期我们介绍了装饰模式在Python中的实现&#xff0c;今天&#xff0c;我们将继续探讨装饰模式&#xff0c;并展示如何在Java中实现它。 装饰模式概述 装饰模式的核心思想是将功能附加到对象上&#xff0c;而不是通过继承来实现&#xff0c;这种模式…

安防监控视频平台LntonAIServer视频监控管理平台裸土检测算法

LntonAIServer裸土检测算法代表了一种先进的土地监测技术&#xff0c;它利用人工智能的强劲能力&#xff0c;实现了对裸土区域的自动识别和实时监测。该算法的推出&#xff0c;为环境保护、农业管理以及城市规划等多个领域提供了创新的解决方案&#xff0c;其应用前景广阔&…