当前位置: 首页 > news >正文

23种经典设计模式:单例模式篇(C++)

前言:        

        博主将从此篇单例模式开始逐一分享23种经典设计模式,并结合C++为大家展示实际应用。内容将持续更新,希望大家持续关注与支持。

什么是单例模式?

        单例模式是设计模式的一种(属于创建型模式 (Creational Patterns) ),它确保某个类只有一个实例,并为该实例提供一个全局访问点。它常用于那些在整个系统中只需要一个实例的类,例如配置管理、日志记录、线程池、缓存等。

为什么选择单例模式?

1. 确保唯一性

        有些时候,我们需要确保某个对象在整个系统中只存在一个。这样可以避免因为多次实例化导致的资源浪费或不一致性。

2. 节省资源

        如果一个对象初始化需要大量资源,例如读取配置文件或建立数据库连接,那么多次实例化就可能导致不必要的开销。

3. 提供全局访问点

        这让其他对象可以轻松地访问到该实例,并与之交互。

4. 单例模式的不足:

        万事万物都没有绝对的好,不然也不会有23种设计模式,过度依赖单例模式可能使代码变得紧耦合和难以测试。因此,当考虑使用单例模式时,应当仔细权衡其优点和潜在的问题。        

单例模式的分类?

单例模式的具体实现? 

1. 饿汉式

  • 特点:在类加载时就完成了初始化,静态成员对象的创建是在类加载时完成的。
  • 优点:线程安全(基于类加载机制,避免了多线程同步问题)。
  • 缺点:不是懒加载,可能造成资源浪费。
class Singleton {
private:// Singleton的私有静态实例static Singleton instance;// 私有构造函数确保只能通过getInstance方法来访问Singleton实例Singleton() {}public:// 公共静态方法,用于获取Singleton实例static Singleton& getInstance() {return instance;}
};// 初始化静态的Singleton实例
Singleton Singleton::instance;

2. 懒汉式

  • 特点:在第一次调用时实例化。
  • 优点:懒加载,只有在真正需要对象时才会创建。
  • 缺点:需要处理线程安全问题。
class Singleton {
private:// Singleton的私有静态指针实例static Singleton* instance;// 私有构造函数确保只能通过getInstance方法来访问Singleton实例Singleton() {}public:// 公共静态方法,用于获取Singleton实例。如果实例不存在,就创建一个。static Singleton* getInstance() {if (!instance) { // 判断instance是否为空instance = new Singleton(); // 如果为空,则新建一个Singleton对象}return instance; // 返回Singleton对象的指针}
};// 初始化静态的Singleton指针实例为nullptr
Singleton* Singleton::instance = nullptr;

 3. 懒汉式(带锁)

  • 特点:在首次请求对象时创建实例,但加入了互斥锁以确保线程安全。
  • 优势:懒加载,线程安全。
  • 劣势:每次访问时都需要加锁,可能会有性能开销。
class Singleton {
private:static Singleton* instance;static std::mutex mtx; // 用于同步的互斥锁Singleton() {}public:static Singleton* getInstance() {std::lock_guard<std::mutex> lock(mtx); // 直接锁定if (!instance) {instance = new Singleton();}return instance;}
};Singleton* Singleton::instance = nullptr;
std::mutex Singleton::mtx;

4. 双重检查锁定(DCL, Double Checked Locking)

  • 特点:结合了懒汉式和synchronized同步锁。
  • 优点:懒加载,线程安全,且性能较高。
class Singleton {
private:// Singleton的私有静态指针实例static Singleton* instance;// 用于同步的互斥锁static std::mutex mtx;Singleton() {}public:// 这里使用了双重检查锁定来确保线程安全static Singleton* getInstance() {if (!instance) { // 第一次检查,不加锁std::lock_guard<std::mutex> lock(mtx); // 加锁if (!instance) { // 第二次检查,已加锁instance = new Singleton(); }}return instance; }
};Singleton* Singleton::instance = nullptr;
std::mutex Singleton::mtx;

5. 静态局部变量(C++11)

        利用C++11特性,局部静态变量已经是线程安全的,并且无需额外的锁或同步机制。

class Singleton {
public:// 公共静态方法,用于获取Singleton实例的引用。// 这里利用了局部静态变量的特性,该变量只会初始化一次,并且这个初始化过程在C++11及以上是线程安全的。static Singleton& getInstance() {static Singleton instance;  // 局部静态变量return instance;            // 返回这个局部静态变量的引用}private:// 私有构造函数确保只能通过getInstance方法来访问Singleton实例Singleton() {}
};

6. 使用std::once_flagstd::call_once(C++11及以上):

  • 特点:确保某个代码块只被执行一次。
  • 优势:线程安全,性能较好。
  • 劣势:依赖于C++11及以上版本的特性。
class Singleton {
private:// Singleton的私有静态指针实例static Singleton* instance;static std::once_flag onceFlag;// 私有构造函数Singleton() {}public:// 删除拷贝构造函数和赋值操作符,确保不能拷贝Singleton(const Singleton& other) = delete;Singleton& operator=(const Singleton& other) = delete;// 公共静态方法,用于获取或创建Singleton实例static Singleton* getInstance() {std::call_once(onceFlag, []() {instance = new Singleton();});return instance;}
};// 初始化静态成员
Singleton* Singleton::instance = nullptr;
std::once_flag Singleton::onceFlag;

开发中的选择?

在实际开发中,选择单例模式的具体实现通常取决于以下因素:

  1. 线程安全性需求:在多线程应用中,单例模式的实现必须是线程安全的。但如果你知道应用永远不会在多线程环境中运行,你可以选择一个不考虑线程安全的简单实现。

  2. 性能考虑:某些单例实现(例如每次访问时都加锁的懒汉式)可能会对性能产生负面影响。但在现代硬件上,这种影响通常可以忽略不计,除非你的代码在高频、高并发场景下运行。

  3. C++版本:在C++11及更高版本中,局部静态变量的初始化是线程安全的,这使得某些单例实现变得更为简洁和可靠。

基于上述因素,以下是在实际开发中经常使用的单例模式实现:

  1. 局部静态变量(推荐,尤其是C++11及以上):

    这种方法简洁、线程安全,并且无需额外的锁或同步机制。

  2. 双重检查锁定(DCL, Double Checked Locking): 这在C++11之前可能是线程安全的选择,但需要谨慎使用,因为在某些老的编译器和硬件上可能会出现问题。

  3. 使用std::call_oncestd::once_flag: 这是C++11及以上版本提供的线程安全方法,可以确保对象只初始化一次。

  4. 饿汉式: 在程序启动时就创建实例。这种方法简单并且线程安全,但可能会导致不必要的资源浪费,特别是当单例对象很大或初始化成本很高时。

  5. 懒汉式(带锁): 在首次请求时创建实例,并使用互斥锁确保线程安全。这种方式在性能敏感的场景中可能不是最佳选择。

结论:

        单例模式有许多不同的实现,每种实现都有其适用的场景和优缺点。在实践中,选择哪种实现需要根据具体需求和上下文进行权衡。

        本文侧重于介绍单例模式在C++中的使用方法,若读者有不同的的理解和看法,欢迎在评论区留言!

相关文章:

23种经典设计模式:单例模式篇(C++)

前言&#xff1a; 博主将从此篇单例模式开始逐一分享23种经典设计模式&#xff0c;并结合C为大家展示实际应用。内容将持续更新&#xff0c;希望大家持续关注与支持。 什么是单例模式&#xff1f; 单例模式是设计模式的一种&#xff08;属于创建型模式 (Creational Pa…...

ros中对move_base的调用

move_base包中自带costmap2d, global planner 等功能 也可以直接调用其中make_plan进行路径规划 #include "geometry_msgs/PoseStamped.h" #includde "nav_msgs/GetPlan.h"void fillPathRequest(nav_msgs::GetPlan::Request &request, float start_x…...

Git从本地库撤销已经添加的文件或目录

场景 在提交时, 误将一个目录添加到了暂存区, 而且commit 了本地库,同批次commit 的还有其他需要提交的文件。 commit 之后发现这个目录下所有的文件都不需要提交, 现在需要撤销这个提交, 使这个目录不被push到远端库。 这里以远端服务器github 为例,在Git GUI下看到的…...

百度SEO优化的特点(方式及排名诀窍详解)

百度SEO优化的特点介绍&#xff1a; 百度SEO优化是指对网站进行优化&#xff0c;使其在百度搜索引擎中获得更好的排名&#xff0c;进而获取更多的流量和用户。百度SEO优化的特点是综合性强、效果持久、成本低廉、投资回报高。百度的搜索算法不断更新&#xff0c;所以长期稳定的…...

Gin 文件上传操作(单/多文件操作)

参考地址: 单文件 | Gin Web Framework (gin-gonic.com)https://gin-gonic.com/zh-cn/docs/examples/upload-file/single-file/ 单文件 官方案例: func main() {router := gin.Default()// 为 multipart forms 设置较低的内存限制 (默认是 32 MiB)router.MaxMultipartMem…...

分类预测 | MATLAB实现KOA-CNN-LSTM开普勒算法优化卷积长短期记忆神经网络数据分类预测

分类预测 | MATLAB实现KOA-CNN-LSTM开普勒算法优化卷积长短期记忆神经网络数据分类预测 目录 分类预测 | MATLAB实现KOA-CNN-LSTM开普勒算法优化卷积长短期记忆神经网络数据分类预测分类效果基本描述程序设计参考资料 分类效果 基本描述 1.MATLAB实现KOA-CNN-LSTM开普勒算法优化…...

Qt应用开发(基础篇)——列表视图 QListView

一、前言 QListView类继承于QAbstractItemView类&#xff0c;提供了一个列表或者图标视图的模型。 视图基类 QAbstractItemView QListView效果相当于Windows文件夹右键->查看->图标和列表&#xff0c;使用setViewMode()设置视图模式&#xff0c;并且提供setIconSize()函数…...

vue-6

一、声明式导航-导航链接 1.需求 实现导航高亮效果 如果使用a标签进行跳转的话&#xff0c;需要给当前跳转的导航加样式&#xff0c;同时要移除上一个a标签的样式&#xff0c;太麻烦&#xff01;&#xff01;&#xff01; 2.解决方案 vue-router 提供了一个全局组件 router…...

温度在线检测技术在电力电缆线路的应用

在电力电缆的日常运行检测中&#xff0c;针对电缆温度的状况&#xff0c;所采用的电力温度在线检测技术也得到了大范围的普及。电网系统中&#xff0c;其单位时间内可输送的电力能源受到其温度的变化影响。因此&#xff0c;采用更有效的方式实时检测电缆系统运行温度&#xff0…...

2023年中国自动化微生物样本处理系统竞争现状及行业市场规模分析[图]

微生物检测能够对感染性疾病的病原体或者代谢物进行检测分析&#xff0c;是IVD的细分领域之一。2022年中国体外诊断市场规模1424亿元。 2015-2022年中国体外诊断市场规模 资料来源&#xff1a;共研产业咨询&#xff08;共研网&#xff09; 微生物检测由于样本类型多样&#xf…...

硬链接和软连接的区别

软链接&#xff08;也称为软连接或符号链接&#xff09;是一种特殊的文件&#xff0c;其内容是另一个文件的路径。当你使用软链接时&#xff0c;实际上是在操作另一个文件。软链接的优点是它可以跨文件系统使用&#xff0c;因此可以跨分区或磁盘链接文件。此外&#xff0c;软链…...

保护隐私与增强网络安全之网络代理技术

目录 前言 一、网络代理技术原理 二、网络代理技术类型 1. HTTP代理 2. SOCKS代理 3. DNS代理 4. 加密代理 5. 反向代理 三、网络代理技术应用 1. 加速网络访问速度 2. 绕过网络限制 3. 保护个人隐私 4. 节省带宽 5. 改善网络安全 四、网络代理技术优缺点 网络…...

【每日一题】CF1680C. Binary String | 双指针 | 简单

题目内容 原题链接 给定一个长度为 n n n 的 01 01 01 字符串&#xff0c;对于一个子串 s u b sub sub &#xff0c;子串内部的 0 0 0 的数量为 x x x &#xff0c;子串以外的 1 1 1 的数量为 y y y &#xff0c;子串的代价为 m a x ( x , y ) max(x, y) max(x,y) &…...

10.selenium进阶

文章目录 1、嵌套网页1、1 什么是嵌套页面1、2 selenium获取嵌套页面的数据 2、执行JavaScript代码3、鼠标动作链4、selenium键盘事件5、其他方法5、1 选择下拉框5、2 弹窗的处理 6、selenium设置无头模式7、selenium应对检测小结 1、嵌套网页 ​ 在前端开发中如果有这么一个需…...

【安全】 Java 过滤器 解决存储型xss攻击问题

文章目录 XSS简介什么是XSS?分类反射型存储型 XSS(cross site script)跨站脚本攻击攻击场景解决方案 XSS简介 跨站脚本( cross site script )为了避免与样式css(Cascading Style Sheets层叠样式表)混淆&#xff0c;所以简称为XSS。 XSS是一种经常出现在web应用中的计算机安全…...

一、Excel VBA 是个啥?

Excel VBA 从入门到出门一、Excel VBA 是个啥&#xff1f;二、Excel VBA 简单使用 &#x1f44b;Excel VBA 是个啥&#xff1f; ⚽️1. Excel 中的 VBA 是什么&#xff1f;⚽️2. 为什么 VBA 很重要&#xff1f;⚽️3. 是否有无代码方法可以在 Excel 中实现工作流程自动化&…...

Spring Boot读取配置文件

Spring Boot 是一种用于快速构建基于Spring的应用程序的框架&#xff0c;它提供了很多便利的功能和约定&#xff0c;使开发者可以快速搭建、配置和部署应用程序。在Spring Boot中&#xff0c;读取配置文件是一个非常常见的任务&#xff0c;本文将介绍如何在Spring Boot应用程序…...

spark集群环境下,实现人口平均年龄计算

文章目录 任务目标0. 版本信息1. 计算生成renkou.txt2. 文件上传至spark3. 上传文件时&#xff0c;可能出现的常见错误4. 编写spark文件5. 上传集群6. 集群环境下提交任务 任务目标 在虚拟机上部署spark集群&#xff0c;给定renkou.txt文件&#xff0c;输出平均年龄 renkou.t…...

[羊城杯 2020]black cat - 文件隐写+RCE(hash_hmac绕过)

[羊城杯 2020]black cat 1 解题流程1.1 第一步1.2 第二步1.3 第三步 1 解题流程 1.1 第一步 打开网站有首歌&#xff0c;按F12也是提示听歌&#xff0c;ctf-wscan扫描就flag.php下载歌&#xff0c;用010打开&#xff0c;发现有一段内容if(empty($_POST[Black-Cat-Sheriff]) |…...

智能文件管理助手,轻松实现按数量平均分类文件,高效整理新文件夹!

在我们的电脑或移动设备中&#xff0c;文件管理是我们日常工作和生活中不可或缺的一部分。有时候&#xff0c;我们可能需要将一个文件夹中的大量文件按照数量平均分配到多个新的文件夹中&#xff0c;以便更好地进行整理和管理。现在&#xff0c;我们为您提供了一款智能文件管理…...

融合熵权、灰色关联与TOPSIS的MATLAB实战:构建智能综合评价系统

1. 为什么需要综合评价系统&#xff1f; 做数据分析的朋友们应该都遇到过这样的困扰&#xff1a;面对一堆评价指标和候选方案&#xff0c;到底该怎么科学地做出选择&#xff1f;比如要评选优秀员工&#xff0c;有业绩、考勤、客户评价等多个维度&#xff1b;或者要选择供应商&a…...

小迪安全第9天:算法逆向与加密解密基础

一、加密算法分类与核心特征1.1 三大加密类型对比表格类型代表算法核心特点解密条件成功率单向散列加密MD5、SHA、MAC、CRC不可逆、固定输出、碰撞破解只需密文依赖明文复杂度对称加密AES、DES、3DES加解密用同一密钥、速度快密文密钥模式偏移量99.9%非对称加密RSA、SSL、PKCS公…...

Ollama API 实战:5分钟搞定本地大模型聊天机器人(Python版)

Ollama API 实战&#xff1a;5分钟搞定本地大模型聊天机器人&#xff08;Python版&#xff09; 在AI技术快速发展的今天&#xff0c;本地运行大型语言模型已成为可能。Ollama作为一个轻量级框架&#xff0c;让开发者能够轻松在本地计算机上部署和运行各种开源大模型。本文将带你…...

如何高效使用开源OCR工具:Umi-OCR专业部署与实战应用指南

如何高效使用开源OCR工具&#xff1a;Umi-OCR专业部署与实战应用指南 【免费下载链接】Umi-OCR Umi-OCR: 这是一个免费、开源、可批量处理的离线OCR软件&#xff0c;适用于Windows系统&#xff0c;支持截图OCR、批量OCR、二维码识别等功能。 项目地址: https://gitcode.com/G…...

3步快速恢复ROG游戏本色彩配置文件的终极指南

3步快速恢复ROG游戏本色彩配置文件的终极指南 【免费下载链接】g-helper Lightweight Armoury Crate alternative for Asus laptops. Control tool for ROG Zephyrus G14, G15, G16, M16, Flow X13, Flow X16, TUF, Strix, Scar and other models 项目地址: https://gitcode.…...

AWS CloudFormation 安全最佳实践终极指南:IAM角色与策略配置完全解析

AWS CloudFormation 安全最佳实践终极指南&#xff1a;IAM角色与策略配置完全解析 【免费下载链接】aws-cloudformation-templates awslabs/aws-cloudformation-templates: 是一个包含各种 AWS CloudFormation 模板的存储库。适合查找和学习 AWS CloudFormation 模板的示例&…...

3个革新性视角:Tomato-Novel-Downloader的内容自由解决方案

3个革新性视角&#xff1a;Tomato-Novel-Downloader的内容自由解决方案 【免费下载链接】Tomato-Novel-Downloader 番茄小说下载器不精简版 项目地址: https://gitcode.com/gh_mirrors/to/Tomato-Novel-Downloader 在数字阅读成为主流的今天&#xff0c;我们却常常陷入内…...

ACE协议实战:如何通过AxDOMAIN信号优化多核SoC的缓存一致性?

ACE协议实战&#xff1a;AxDOMAIN信号在多核SoC缓存一致性中的深度优化 1. 多核SoC缓存一致性的工程挑战 在现代嵌入式系统设计中&#xff0c;多核处理器架构已成为提升性能的主流方案。当我们把多个ARM Cortex-A系列核心集成到同一芯片时&#xff0c;缓存一致性管理立即成为系…...

全栈实战应用:基于快马AI快速构建带投稿审稿系统的《构石》期刊官网

全栈实战应用&#xff1a;基于快马AI快速构建带投稿审稿系统的《构石》期刊官网 最近接手了一个学术期刊官网的开发需求&#xff0c;需要实现完整的在线投稿和审稿流程。这个项目涉及前后端联调和数据库设计&#xff0c;正好可以试试用InsCode(快马)平台来快速搭建原型。下面分…...

从概念到生产:使用快马AI生成企业级开yun微服务实战代码

今天想和大家分享一个实战经验&#xff1a;如何用InsCode(快马)平台快速搭建一个生产级可用的微服务项目。这个项目是一个产品目录服务&#xff0c;但重点不在于业务逻辑&#xff0c;而是如何集成企业开发中那些真正实用的技术栈。 项目骨架搭建 首先用Spring Initializr创建…...