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

单例模式 - 单例模式的实现与应用

引言

单例模式(Singleton Pattern)是设计模式中最简单且最常用的模式之一。它确保一个类只有一个实例,并提供一个全局访问点来访问该实例。单例模式常用于需要全局唯一对象的场景,如配置管理、日志记录、线程池等。

本文将详细介绍单例模式的概念、实现方式以及在C++中的应用。

单例模式的概念

单例模式的核心思想是确保一个类只有一个实例,并提供一个全局访问点。这样做的目的是为了避免多个实例之间的冲突,同时节省系统资源。

单例模式的优点

  1. 全局唯一实例:确保一个类只有一个实例,避免多个实例之间的冲突。
  2. 节省资源:由于只有一个实例,可以减少系统资源的消耗。
  3. 全局访问:提供一个全局访问点,方便其他对象访问该实例。

单例模式的缺点

  1. 扩展性差:单例模式通常难以扩展,因为它的实例是全局唯一的。
  2. 测试困难:由于单例模式的全局性,测试时可能会遇到困难。
  3. 线程安全问题:在多线程环境下,单例模式的实现需要考虑线程安全问题。

单例模式的实现

在C++中,单例模式的实现有多种方式,下面我们将介绍几种常见的实现方式。

1. 懒汉式单例模式

懒汉式单例模式是指在第一次使用时才创建实例。这种方式可以节省资源,但需要考虑线程安全问题。

class Singleton {
private:static Singleton* instance;Singleton() {}  // 私有构造函数public:static Singleton* getInstance() {if (instance == nullptr) {instance = new Singleton();}return instance;}
};Singleton* Singleton::instance = nullptr;

2. 饿汉式单例模式

饿汉式单例模式是指在程序启动时就创建实例。这种方式避免了线程安全问题,但可能会浪费资源。

class Singleton {
private:static Singleton* instance;Singleton() {}  // 私有构造函数public:static Singleton* getInstance() {return instance;}
};Singleton* Singleton::instance = new Singleton();

3. 线程安全的懒汉式单例模式

在多线程环境下,懒汉式单例模式需要考虑线程安全问题。可以使用互斥锁(Mutex)来保证线程安全。

#include <mutex>class Singleton {
private:static Singleton* instance;static std::mutex mtx;Singleton() {}  // 私有构造函数public:static Singleton* getInstance() {std::lock_guard<std::mutex> lock(mtx);if (instance == nullptr) {instance = new Singleton();}return instance;}
};Singleton* Singleton::instance = nullptr;
std::mutex Singleton::mtx;

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

双重检查锁定是一种优化后的线程安全单例模式,它减少了锁的使用次数,提高了性能。

#include <mutex>class Singleton {
private:static Singleton* instance;static std::mutex mtx;Singleton() {}  // 私有构造函数public:static Singleton* getInstance() {if (instance == nullptr) {std::lock_guard<std::mutex> lock(mtx);if (instance == nullptr) {instance = new Singleton();}}return instance;}
};Singleton* Singleton::instance = nullptr;
std::mutex Singleton::mtx;

单例模式的应用

单例模式在实际开发中有广泛的应用,以下是一些常见的应用场景:

1. 配置管理

在应用程序中,通常需要一个全局的配置管理器来读取和存储配置信息。使用单例模式可以确保配置管理器只有一个实例,避免配置信息的冲突。

class ConfigManager {
private:static ConfigManager* instance;std::map<std::string, std::string> config;ConfigManager() {}  // 私有构造函数public:static ConfigManager* getInstance() {if (instance == nullptr) {instance = new ConfigManager();}return instance;}void setConfig(const std::string& key, const std::string& value) {config[key] = value;}std::string getConfig(const std::string& key) {return config[key];}
};ConfigManager* ConfigManager::instance = nullptr;

2. 日志记录

日志记录器通常也需要一个全局唯一的实例,以确保所有的日志信息都写入同一个文件或输出流中。

class Logger {
private:static Logger* instance;std::ofstream logFile;Logger() {logFile.open("log.txt", std::ios::app);}public:static Logger* getInstance() {if (instance == nullptr) {instance = new Logger();}return instance;}void log(const std::string& message) {logFile << message << std::endl;}~Logger() {logFile.close();}
};Logger* Logger::instance = nullptr;

3. 线程池

线程池通常也需要一个全局唯一的实例,以管理所有的线程资源。

class ThreadPool {
private:static ThreadPool* instance;std::vector<std::thread> threads;ThreadPool() {}  // 私有构造函数public:static ThreadPool* getInstance() {if (instance == nullptr) {instance = new ThreadPool();}return instance;}void addThread(std::thread&& thread) {threads.push_back(std::move(thread));}void joinAll() {for (auto& thread : threads) {if (thread.joinable()) {thread.join();}}}
};ThreadPool* ThreadPool::instance = nullptr;

总结

单例模式是一种简单但非常实用的设计模式,它确保一个类只有一个实例,并提供一个全局访问点。在C++中,单例模式的实现有多种方式,包括懒汉式、饿汉式、线程安全的懒汉式以及双重检查锁定。单例模式在配置管理、日志记录、线程池等场景中有广泛的应用。

希望本文能帮助你更好地理解单例模式的概念、实现方式以及应用场景。如果你有任何问题或建议,欢迎在评论区留言讨论。

相关文章:

单例模式 - 单例模式的实现与应用

引言 单例模式&#xff08;Singleton Pattern&#xff09;是设计模式中最简单且最常用的模式之一。它确保一个类只有一个实例&#xff0c;并提供一个全局访问点来访问该实例。单例模式常用于需要全局唯一对象的场景&#xff0c;如配置管理、日志记录、线程池等。 本文将详细介…...

hadoop==docker desktop搭建hadoop

hdfs map readuce yarn https://medium.com/guillermovc/setting-up-hadoop-with-docker-and-using-mapreduce-framework-c1cd125d4f7b 清理资源 docker-compose down docker system prune -f...

zookeeper的介绍和简单使用

1 zookerper介绍 zookeeper是一个开源的分布式协调服务&#xff0c;由Apache软件基金会提供&#xff0c;主要用于解决分布式应用中的数据管理、状态同步和集群协调等问题。通过提供一个高性能、高可用的协调服务&#xff0c;帮助构建可靠的分布式系统。 Zookeeper的特点和功能…...

DiffuEraser: 一种基于扩散模型的视频修复技术

视频修复算法结合了基于流的像素传播与基于Transformer的生成方法&#xff0c;利用光流信息和相邻帧的信息来恢复纹理和对象&#xff0c;同时通过视觉Transformer完成被遮挡区域的修复。然而&#xff0c;这些方法在处理大范围遮挡时常常会遇到模糊和时序不一致的问题&#xff0…...

CentOS/Linux Python 2.7 离线安装 Requests 库解决离线安装问题。

root@mwcollector1 externalscripts]# cat /etc/os-release NAME=“Kylin Linux Advanced Server” VERSION=“V10 (Sword)” ID=“kylin” VERSION_ID=“V10” PRETTY_NAME=“Kylin Linux Advanced Server V10 (Sword)” ANSI_COLOR=“0;31” 这是我系统的版本,由于是公司内网…...

World of Warcraft [CLASSIC] Jewelcrafting Gemstone 2

World of Warcraft [CLASSIC] Jewelcrafting & Gemstone 2 珠宝加工与常用宝石列表&#xff08;紫色史诗级&#xff09;&#xff1a; World of Warcraft [CLASSIC] Jewelcrafting & Gemstone_wlk宝石属性一览表-CSDN博客...

AI刷题-最小化团建熟悉程度和

目录 问题描述 输入格式 输出格式 解题思路&#xff1a; 状态表示 状态转移 动态规划数组 预处理 实现&#xff1a; 1.初始化&#xff1a; 2.动态规划部分&#xff1a; &#xff08;1&#xff09;对于已分组状态的&#xff0c;跳过&#xff1a; &#xff08;2&…...

一文详解Filter类源码和应用

背景 在日常开发中&#xff0c;经常会有需要统一对请求做一些处理&#xff0c;常见的比如记录日志、权限安全控制、响应处理等。此时&#xff0c;ServletApi中的Filter类&#xff0c;就可以很方便的实现上述效果。 Filter类 是一个接口&#xff0c;属于 Java Servlet API 的一部…...

应用层协议 HTTP 讲解实战:从0实现HTTP 服务器

&#x1f308; 个人主页&#xff1a;Zfox_ &#x1f525; 系列专栏&#xff1a;Linux 目录 一&#xff1a;&#x1f525; HTTP 协议 &#x1f98b; 认识 URL&#x1f98b; urlencode 和 urldecode 二&#xff1a;&#x1f525; HTTP 协议请求与响应格式 &#x1f98b; HTTP 请求…...

DDD-全面理解领域驱动设计中的各种“域”

一、DDD-领域 在领域驱动设计&#xff08;Domain-Driven Design&#xff0c;DDD&#xff09;中&#xff0c;**领域&#xff08;Domain&#xff09;**指的是软件系统所要解决的特定业务问题的范围。它涵盖了业务知识、规则和逻辑&#xff0c;是开发团队与领域专家共同关注的核心…...

PHP防伪溯源一体化管理系统小程序

&#x1f50d; 防伪溯源一体化管理系统&#xff0c;品质之光&#xff0c;根源之锁 &#x1f680; 引领防伪技术革命&#xff0c;重塑品牌信任基石 我们自豪地站在防伪技术的前沿&#xff0c;为您呈现基于ThinkPHP和Uniapp精心锻造的多平台&#xff08;微信小程序、H5网页&…...

纯css实现div宽度可调整

<!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title>纯css实现div尺寸可调整</title><style…...

C# 中使用Hash用于密码加密

通过一定的哈希算法&#xff08;典型的有MD5&#xff0c;SHA-1等&#xff09;&#xff0c;将一段较长的数据映射为较短小的数据&#xff0c;这段小数据就是大数据的哈希值。他最大的特点就是唯一性&#xff0c;一旦大数据发生了变化&#xff0c;哪怕是一个微小的变化&#xff0…...

如何建设一个企业级的数据湖

建设一个企业级的数据湖是一项复杂且系统化的工程&#xff0c;需要从需求分析、技术选型、架构设计到实施运维等多个方面进行综合规划和实施。以下是基于我搜索到的资料&#xff0c;详细阐述如何建设企业级数据湖的步骤和关键要点&#xff1a; 一、需求分析与规划 明确业务需…...

目标跟踪之sort算法(3)

这里写目录标题 1 流程1 预处理2 跟踪 2 代码 参考&#xff1a;sort代码 https://github.com/abewley/sort 1 流程 1 预处理 1.1 获取离线检测数据。1.2 实例化跟踪器。2 跟踪 2.1 轨迹处理。根据上一帧的轨迹预测当前帧的轨迹&#xff0c;剔除到当前轨迹中为空的轨迹得到当前…...

【java数据结构】HashMapOJ练习题

【java数据结构】HashMapOJ练习题 一、只出现一次的数字二 、随机链表的复制三 、宝石与石头四、坏键盘打字五、前K个高频单词 博客最后附有整篇博客的全部代码&#xff01;&#xff01;&#xff01; 一、只出现一次的数字 只出现一次的数字 思路&#xff1a; 先遍历一遍数组…...

Nginx前端后端共用一个域名如何配置

在 Nginx 中配置前端和后端共用一个域名的情况&#xff0c;通常是通过路径或子路径将请求转发到不同的服务。以下是一个示例配置&#xff0c;假设&#xff1a; 前端静态文件在 /var/www/frontend/。 后端 API 服务运行在 http://127.0.0.1:5000。 域名是 example.com&#xff…...

SpringBoot3+Vue3开发学生选课管理系统

功能介绍 分三个角色登录&#xff1a;学生登录&#xff0c;老师登录&#xff0c;教务管理员登录&#xff0c;不同用户功能不同&#xff01; 1.学生用户功能 选课记录&#xff0c;查看选课记录&#xff0c;退选。选课管理&#xff0c;进行选课。通知管理&#xff0c;查看通知消…...

Linux系统 C/C++编程基础——基于GTK+的图形用户界面编程

ℹ️大家好&#xff0c;我是练小杰&#xff0c;今天星期三了&#xff0c;距离除夕又少了一天&#xff0c;新年的钟声就快敲响了&#x1f606; 本文是有关Linux C/C编程中的基于GTK的图形用户界面编程知识点&#xff0c;后续会不断添加相关内容 ~~ 回顾:【使用make工具和Makefil…...

【Leetcode 每日一题】40. 组合总和 II

问题背景 给定一个候选人编号的集合 c a n d i d a t e s candidates candidates 和一个目标数 t a r g e t target target&#xff0c;找出 c a n d i d a t e s candidates candidates 中所有可以使数字和为 t a r g e t target target 的组合。 c a n d i d a t e s c…...

python 变量范围的定义与用法

文章目录 1. 局部变量&#xff08;Local Scope&#xff09;示例&#xff1a; 2. 嵌套函数变量&#xff08;Enclosing Scope&#xff09;示例&#xff1a;说明&#xff1a; 3. 全局变量&#xff08;Global Scope&#xff09;示例&#xff1a;说明&#xff1a; 4. 内置变量&#…...

TRTC实时对话式AI解决方案,助力人机语音交互极致体验

近年来&#xff0c;AI热度持续攀升&#xff0c;无论是融资规模还是用户热度都大幅增长。2023 年&#xff0c;中国 AI 行业融资规模达2631亿人民币&#xff0c;较2022年上升51%&#xff1b;2024年第二季度&#xff0c;全球 AI 初创企业融资规模为 240 亿美金&#xff0c;较第一季…...

dev c++ ‘unordered_set‘ does not name a type

参考:https://blog.csdn.net/Zaczc/article/details/142531525 启用C11标准步骤 工具->编译选项 勾选编译时加入以下命令 在空白处添加:-stdc11 单击确定&#xff0c;启用成功...

算法每日双题精讲 —— 二分查找(寻找旋转排序数组中的最小值,点名)

&#x1f31f;快来参与讨论&#x1f4ac;&#xff0c;点赞&#x1f44d;、收藏⭐、分享&#x1f4e4;&#xff0c;共创活力社区。 &#x1f31f; 别再犹豫了&#xff01;快来订阅我们的算法每日双题精讲专栏&#xff0c;一起踏上算法学习的精彩之旅吧&#x1f4aa; 在算法的…...

three.js+WebGL踩坑经验合集(4.2):为什么不在可视范围内的3D点投影到2D的结果这么不可靠

上一篇&#xff0c;笔者留下了一个问题&#xff0c;three.js内置的THREE.Vector3.project方法算出来的结果对于超出屏幕可见范围的点来说错得相当离谱。 three.jsWebGL踩坑经验合集(4.1):THREE.Line2的射线检测问题&#xff08;注意本篇说的是Line2&#xff0c;同样也不是阈值…...

Kafka运维宝典 (二)- kafka 查看kafka的运行状态、broker.id不一致导致启动失败问题、topic消息积压量告警监控脚本

Kafka运维宝典 &#xff08;二&#xff09; 文章目录 Kafka运维宝典 &#xff08;二&#xff09;一、kafka broker.id冲突问题1. broker.id 冲突的影响2. 如何发现 broker.id 冲突3. 解决 broker.id 冲突的方法4. broker.id 配置管理5. 集群启动后确认 broker.id 唯一性6. brok…...

全球AI模型百科全书,亚马逊云科技Bedrock上的100多款AI模型

今天小李哥给大家介绍的是亚马逊云科技上的AI模型管理平台Amazon Bedrock上的Marketplace&#xff0c;这是亚马逊云科技在今年re:Invent发布的一个全新功能&#xff0c;将亚马逊的电商基因带到了其云计算平台&#xff0c;让我们能够通过Amazon Bedrock访问100多种流行、新兴和专…...

微信小程序中常见的 跳转方式 及其特点的表格总结(wx.navigateTo 适合需要返回上一页的场景)

文章目录 详细说明总结wx.navigateTo 的特点为什么 wx.navigateTo 最常用&#xff1f;其他跳转方式的使用频率总结 以下是微信小程序中常见的跳转方式及其特点的表格总结&#xff1a; 跳转方式API 方法特点适用场景wx.navigateTowx.navigateTo({ url: 路径 })保留当前页面&…...

【Elasticsearch】index:false

在 Elasticsearch 中&#xff0c;index 参数用于控制是否对某个字段建立索引。当设置 index: false 时&#xff0c;意味着该字段不会被编入倒排索引中&#xff0c;因此不能直接用于搜索查询。然而&#xff0c;这并不意味着该字段完全不可访问或没有其他用途。以下是关于 index:…...

新版IDEA创建数据库表

这是老版本的IDEA创建数据库表&#xff0c;下面可以自己勾选Not null&#xff08;非空),Auto inc&#xff08;自增长),Unique(唯一标识)和Primary key&#xff08;主键) 这是新版的IDEA创建数据库表&#xff0c;Not null和Auto inc可以看得到&#xff0c;但Unique和Primary key…...