【C++】单例模式

文章目录

  • 一. 介绍
  • 二. 饿汉模式
  • 三. 懒汉模式
  • 四. 饿汉模式和懒汉模式对比

一. 介绍

单例模式是属于设计模式的一种,那什么是设计模式呢?

设计模式(Design Pattern)是一套被反复使用、多数人知晓的、经过分类的、代码设计经验的总结。为什么会产生设计模式这样的东西呢?就像人类历史发展会产生兵法一样。最开始部落之间打仗时都是人拼人的对
砍;后来春秋战国时期,七国之间经常打仗,就发现打仗也是有套路的,后来孙子就总结出了《孙子兵法》。孙子兵法就类似于一种打仗的“设计模式”。

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

一个类只能创建一个对象,即单例模式。该模式可以保证全局(一个进程中)只有一个唯一的实例对象,并提供一个访问它的全局访问点,该实例对象可以被所有线程访问到。比如在某个服务器程序中,该服务器的配置信息存放在一个文件中,这些配置数据由一个单例对象统一读取,然后服务进程中的其他对象再通过这个单例对象获取这些配置信息,这种方式简化了在复杂环境下的配置管理。

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

二. 饿汉模式

介绍:就是说不管你将来用或者不用,程序启动时(即 main 函数执行之前)就会创建单例对象。

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

实现方法

  • 构造函数私有:防止外部构造单例对象
  • 防拷贝:禁用拷贝构造和赋值运算符重载函数,防止外部拷贝单例类对象
  • 提供接口:在单例类中定义一个自身类的静态对象,这个对象就是单例对象,设计一个静态方法返回这个单例对象的地址给外部。

通过上面三步就能做到一个类只能创建一个对象,且同一进程下的各线程可以通过一个统一的接口拿到这个实例对象。

代码示例

class Singleton
{
public:// 提供访问单例对象的接口Singleton* GetInstance(){return &_inst;}private:// 单例对象static Singleton _inst;// 构造函数私有Singleton();// 放拷贝Singleton(const Singleton&) = delete;Singleton& operator=(Singleton&) = delete;
};// 单例对象存储在静态区中
// 在程序入口之前就完成单例对象的初始化
Singleton Singleton::_inst;

补充说明

在这里插入图片描述

三. 懒汉模式

介绍:如果单例对象构造十分耗时或者占用很多系统资源,比如加载数据库啊, 初始化网络连接啊,读取文件啊等等,而且有可能该对象在程序运行时不会用到,那么也要在程序一开始就进行初始化,就会导致程序启动时非常的缓慢。 所以这种情况使用懒汉模式(延迟加载)更好。

特点:第一次使用实例对象时,才会创建对象,进程启动无负载。且当系统中有多个单例实例时,启动顺序可以自由控制。

实现方法

  • 防构造:把构造函数私有,这样外部就不能实例化对象
  • 防拷贝:禁用拷贝构造和赋值运算负重载函数,防止外部对我们的单例对象进行拷贝
  • 提供一个GetInstance()接口获取单例对象

代码示例

class Singleton
{
public:static Singleton* GetInstance(){// 保护第一次需要加锁,后面都不需要加锁的场景,可以使用双检查加锁// 特点:第一次需要加锁,后面不再加锁,保护线程安全,同时提高了效率if (_inst == nullptr){_mtx.lock();if (_inst == nullptr){_inst = new Singleton();}_mtx.unlock();}return _inst;}private:static mutex _mtx;// 互斥锁static Singleton* _inst;// 单例对象指针// 防构造(把构造函数设为私有)Singleton() {};// 防拷贝(禁用拷贝构造)Singleton(const Singleton&) = delete;Singleton& operator=(const Singleton&) = delete;// 防拷贝(禁用赋值运算负重载)
};// 静态成员初始化
mutex Singleton::_mtx; 
Singleton* Singleton::_inst = nullptr;

其他版本的懒汉

利用静态对象的特性:

  • 静态对象的初始化语句只会执行一次
  • 创建一个静态对象的过程是原子的

这样我们可以不用加锁,直接在接口中创建一个静态单例对象,然后返回单例对象的地址给外部即可。

class Singleton
{
public:static Singleton* GetInstance(){// 静态对象的初始化只会执行一次static Singleton _inst;return &_inst;}private:Singleton() {};Singleton(const Singleton&) = delete;Singleton& operator=(const Singleton&) = delete;
};

缺点:

  • 单例对象创建在静态区,如果单例对象过大,存储在静态区不太合适
  • 因为它在静态区,所以我们无法主动释放单例对象

四. 饿汉模式和懒汉模式对比

饿汉

  • 优点:简单
  • 缺点:
    • 如果单例对象构造函数的工作较多,会导致程序启动慢,迟迟进不了入口 main 函数
    • 如果系统中有多个单例对象,且它们之间有初始化的耦合关系,饿汉模式无法控制它们的初始化顺序

懒汉

  • 优点:需要时才调用,可以达到延迟加载的效果
  • 确定:相对于饿汉,实现起来更复杂,需要加锁和双检查

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

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

相关文章

产品经理如何科学的进行需求调研?

导语:作为产品经理,需求调研是开展工作的重要环节之一。科学、有效地进行需求调研不仅可以帮助产品经理更好地了解用户需求,还能指导产品设计和功能开发,提升产品的竞争力。本文将介绍几种科学的方法和技巧,帮助产品经…

嵌入式MCU都有什么高级用法?

嵌入式MCU都有什么高级用法? 您举的几个例子,确实是MCU外设的一些高端玩法。只是不知道您是否想过,既然这些机制是被 人设计出来的,那它就是种标准用法。从微控制器的发展历程来看,许多硬件机制都是有了实际 需求后才…

nodejs+vue 网上招聘系统elementui

第3章 系统分析 5 3.1 需求分析 5 3.2 系统可行性分析 5 3.2.1技术可行性:技术背景 5 3.2.2经济可行性 6 3.2.3操作可行性: 6 3.3 项目设计目标与原则 6 3.4系统流程分析 7 3.4.1操作流程 7 3.4.2添加信息流程 8 3.4.3删除信息流程 9 第4章 系统设计 11 …

进阶指针(三)--- qsort函数(快速排序)的使用和(用冒泡排序)模拟实现

✨博客主页:小钱编程成长记 🎈博客专栏:进阶C语言 🎈推荐相关博文:进阶C语言(一)、进阶C语言(二) 进阶指针(三) 8.回调函数(下&#x…

ThreeJS-3D教学四-光源

three模拟的真实3D环境,一个非常炫酷的功能便是对光源的操控,之前教学一中已经简单的描述了多种光源,这次咱们就详细的讲下一些最常见的光源: AmbientLight 该灯光在全局范围内平等地照亮场景中的所有对象。 该灯光不能用于投射阴…

Windows系统利用cpolar内网穿透搭建Zblog博客网站并实现公网访问内网!

文章目录 1. 前言2. Z-blog网站搭建2.1 XAMPP环境设置2.2 Z-blog安装2.3 Z-blog网页测试2.4 Cpolar安装和注册 3. 本地网页发布3.1. Cpolar云端设置3.2 Cpolar本地设置 4. 公网访问测试5. 结语 1. 前言 想要成为一个合格的技术宅或程序员,自己搭建网站制作网页是绕…

ElementUI之首页导航+左侧菜单->mockjs,总线

mockjs总线 1.mockjs 什么是Mock.js 前后端分离开发开发过程当中,经常会遇到以下几个尴尬的场景: - 老大,接口文档还没输出,我的好多活干不下去啊! - 后端小哥,接口写好了没,我要测试啊&#x…

【前端】ECMAScript6从入门到进阶

【前端】ECMAScript6从入门到进阶 1.ES6简介及环境搭建 1.1.ECMAScript 6简介 (1)ECMAScript 6是什么 ECMAScript 6.0(以下简称 ES6)是 JavaScript 语言的下一代标准,已经在2015年6月正式发布了。它的目标&#xff…

【sgTileImage】自定义组件:瓦片图拖拽局部加载、实现以鼠标为中心缩放

特性&#xff1a; 支持缩放瓦片图&#xff0c;定义瓦片图初始缩放比例&#xff0c;以鼠标所在位置为中心缩放支持局部拖拽加载 sgTileImage源码 <template><div :class"$options.name"><div class"sg-ctrl"><label>缩放百分比&l…

ElasticSearch映射与模板介绍

一、前言 前面有相关系列文章介绍了ES的基本概念和各种版本SDK的使用&#xff0c;ES现在已升级到8.5版本&#xff0c;有些概念和SDK用法都有很大变化&#xff0c;后续ES相关的文章会以8.3版本为基准介绍一些实际中应用需要掌握的概念以及一些比较实际的例子。 二、映射 ES环…

Flask配合Echarts写一个动态可视化大屏

ch 技术 后端&#xff1a;flask 可视化&#xff1a;echarts 前端&#xff1a;HTMLJavaScriptcss 大屏布局 大屏拆分 案例项目中大屏可按版块进行拆解&#xff0c;会发现这里大屏主要由标题、折线图、柱状图、地图、滚动图和词云等组成&#xff0c;整体可切分为8个版块&…

Unity 制作登录功能02-创建和链接数据库(SQlite)

国际惯例&#xff1a;先看效果 1.SQlite是一种嵌入型数据库 在Unity开发游戏时使用SQLite有多种原因&#xff0c;以下是其中一些主要原因&#xff1a; 嵌入式数据库&#xff1a;SQLite是一个嵌入式数据库引擎&#xff0c;这意味着它不需要单独的服务器进程。这使得使用SQLite非…

VUE2项目:尚品汇VUE-CLI脚手架初始化项目以及路由组件分析(一)

标题 环境VUE2目录publicassetscomponentsmain.jsbabel.config.jspackage.jsonvue.config.js 项目路由分析Header与Footer非路由组件完成Header示例 路由组件的搭建声明式导航编程式导航 Footer组件的显示与隐藏路由传递参数重写push和replace三级联动组件拆分附件 环境 前提要…

子序列问题集合

子序列问题 删除一次得到的最大和最大子数组和最长公共子序列&#xff1a;最长上升子序列&#xff08;要输出序列&#xff0c;和最大长度&#xff09;1.dp2.贪心二分 导弹拦截 &#xff08;最长上升/下降子序列长度&#xff09; 删除一次得到的最大和 class Solution { public:…

Elasticsearch基础篇(二):Elasticsearch在windows和liunx上的安装部署

Elasticsearch简介 前言1. Windows环境部署Elasticsearch1.1 下载并解压Elasticsearch压缩包1.2 命令行启动elasticsearch1.3 验证是否成功启动elasticsearch1.4 关闭Elasticsearch1.5 在Windows上安装Elasticsearch作为服务 2. Liunx环境部署Elasticsearch安装 Elasticsearch …

Android Studio 的android.jar文件在哪儿

一般在&#xff1a;C:\Users\admin\AppData\Local\Android\Sdk\platforms\android-33下&#xff08;不一定是33&#xff0c;这个得看你Android Studio->app->builde.gradle的targetSdk是多少&#xff09; 怎么找&#xff1a; 1.打开Android Studio 粘贴地址后&#xff0…

UE学习记录07----C++中使用事件委托

1.c定义多播委托&#xff0c;示例代码&#xff1a; #include "Delegates/Delegate.h"DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FMyDelegate, UObject*, SelectAgent);/****/ UCLASS(Blueprintable, DisplayName "VM_PlaceEntity") class PR_PLACEE…

在nodejs中如何防止ssrf攻击

在nodejs中如何防止ssrf攻击 什么是ssrf攻击 ssrf&#xff08;server-side request forgery&#xff09;是服务器端请求伪造&#xff0c;指攻击者能够从易受攻击的Web应用程序发送精心设计的请求的对其他网站进行攻击。(利用一个可发起网络请求的服务当作跳板来攻击其他服务)…

word 多级目录的问题

一、多级标题自动编号 --> 制表符 -> 空格 网址&#xff1a; 【Word技巧】2 标题自动编号——将多级列表链接到样式 - YouTube 二、多级列表 --> 正规形式编号 网址&#xff1a;Word 教学 - 定框架&#xff1a;文档格式与多级标题&#xff01; - YouTube 三、目…

【项目】基于C++11实现的数据库连接池

文章目录 前置知识关键技术点项目背景连接池功能点介绍MySQL Server参数介绍功能设计连接池功能点介绍开发平台选型 关于MySQL数据库编程MySQL接口介绍 测试表设计Connection设计数据库配置文件mysql.conf日志文件log.hppConnectionPool设计压力测试源码链接&#xff1a; 前置知…