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

【C++几种单例模式解读及实现方式】

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • 一、单例是什么?
  • 二、解读
    • 1.懒汉式
    • 2.饿汉式
    • 3.static变量特性
    • 4.call_once特性
  • 总结


前言

单例模式几乎是每种语言都不可少的一种设计模式,今天就针对C++语言来解读下集中单例模式,并给出代码说明。


一、单例是什么?

单例就是单实例,简而言之内存中只存在这一个实例,在很多场景下很有用,比如线程池内存池等等。

二、解读

按照创建时机可以分为饿汉式懒汉式。所谓饿汉式就是程序启动的时候立即创建,饿汉式就是需要的时候创建。

1.懒汉式

懒汉式顾名思义,不会主动创建,直到主动获取才创建。懒汉式又主要分为两种,线程安全线程不安全。接下来分别介绍这几种和提供源代码示例。

简单模式:

class Singleton {static Singleton *getInstance() {if (instance == nullptr) {instance = new Singleton();}return instance;}private:static Singleton *instance;};Singleton *Singleton::instance = nullptr;

优点:性能和饿汉式差不多,没有锁,性能不会损失
缺点:线程不安全
总结:需要自己确保线程安全,比如启动线程前就要创建好,避免竞争条件产生

线程安全:

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

优点:线程安全,随时随地都是安全的
缺点:性能差,每次获取实例都要上锁
总结:不建议使用

双重检查锁:

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

优点:线程安全,性能比上面的强
缺点:性能有轻微损耗,只有第一次创建才需要上锁,后面访问不需要上锁
总结:强烈推荐,既解决了线程安全问题,又解决了性能问题

2.饿汉式

不会产生数据竞争,程序启动时就创建和,在竞争条件出现之前创建完成,所以先天是线程安全的。

class Singleton {public:static Singleton &getInstance() {return instance;}private:static Singleton instance;};Singleton Singleton::instance;

优点:线程安全,性能最好
缺点:无论需不需要都会创建,会浪费资源
总结:可用但不太推荐

3.static变量特性

C++11之后static修饰的局部变量有一个很重要的特性:初始化的时候会自动加锁,这个特性是编译器负责维护的。所以可以借用这个特性开发一个单例模式,一定是线程安全的,而且提供不俗的性能

注:这个单例又叫米尔斯单例(Meyers' Singleton)

class Singleton {public:static Singleton &getInstance() {static Singleton instance;return instance;}private:Singleton() {}public:Singleton(const Singleton &) = delete;Singleton &operator=(const Singleton &) = delete;};

优点:线程安全,性能不俗
缺点:初始化上锁略微拖慢性能,后面正常获取,C++11以后版本才行
总结:极其推荐

4.call_once特性

除了米尔斯单例,还有一个C++11的新特性可以设计单例,这个特性我们平常容易忽视,那就是call_once。它也是一种线程同步机制,C++保证call_once保护的方法只被调用一次

#include <atomic>
class Singleton {public:static Singleton& getInstance(){std::call_once(flag,[]{instance = new Singleton();});return *instance;}private:static Singleton* instance;static std::once_flag flag;};Singleton* Singleton::instance = nullptr;std::once_flag Singleton::flag;

优点:线程安全,性能不俗,针对方法可以同时初始化多个资源
缺点:第一次调用拖慢性能,后面就不会了,C++11以后版本才行
总结:和米尔斯很像,但是实现比米尔斯复杂,推荐指数放在米尔斯单例之后


总结

1、C++11以上版本优先使用米尔斯单例,比双重检查锁性能强
2、其他场景建议双重检查锁,call_once酌情使用

相关文章:

【C++几种单例模式解读及实现方式】

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、单例是什么&#xff1f;二、解读1.懒汉式2.饿汉式3.static变量特性4.call_once特性 总结 前言 单例模式几乎是每种语言都不可少的一种设计模式&#xff0c…...

QT开发--串口通信

第十六章 串口通信 16.1 串口通信基础 串口通信主要通过DB9接口&#xff0c;适用于短距离&#xff08;<10米&#xff09;。关键参数包括&#xff1a; 波特率&#xff1a;每秒传输bit数&#xff0c;如9600。数据位&#xff1a;信息包中的有效数据位数。停止位&#xff1a;…...

数据库(至少还的再花两天 )

1 连接查询 左连接 右连接 2 聚合函数 SQL 统计求和 求最值 count sum avg max min 3 SQL关键字 limit 分页 group by 分组 distinct 去重 4 Select执行顺序 from where group by order by 5 数据库三范式 原子性 唯一性 直接性 6 存储引擎 MyISAM InnoDB 7 …...

网络安全公司及其主要产品介绍

以下是一些全球领先的网络安全公司及其主要产品介绍&#xff1a; 一、思科&#xff08;Cisco&#xff09; 思科是全球最大的网络设备供应商之一&#xff0c;其网络安全产品以企业级解决方案为主&#xff0c;覆盖多种安全需求。 Cisco ASA&#xff08;Adaptive Security Appli…...

orjson:高性能的Python JSON库

在Python中处理JSON数据是一项常见任务,标准库的json模块虽然功能齐全,但在性能方面还有提升空间。今天我要向大家介绍一个出色的第三方JSON库 - orjson。 orjson简介 orjson是一个快速、正确的Python JSON库。它具有以下主要特点: 性能卓越 - 在序列化和反序列化方面都比标准…...

常见几大排序算法

排序算法是计算机科学中的基本算法&#xff0c;它们将一个无序的数组或列表按特定顺序进行排列&#xff08;如升序或降序&#xff09;。常见的排序算法可以根据其时间复杂度、空间复杂度和适用场景分类。以下是几种常见的排序算法&#xff1a; 1. 冒泡排序&#xff08;Bubble …...

Linux下CMake入门

CMake的基础知识 什么是 CMake CMake 是一个跨平台的构建工具&#xff0c;主要用于管理构建过程。CMake 不直接构建项目&#xff0c;而是生成特定平台上的构建系统&#xff08;如 Unix 下的 Makefile&#xff0c;Windows 下的 Visual Studio 工程&#xff09;&#xff0c;然后…...

网络资源模板--Android Studio 实现简易记事本App

目录 一、项目演示 二、项目测试环境 三、项目详情 四、完整的项目源码 一、项目演示 网络资源模板--基于Android studio 实现的简易记事本App 二、项目测试环境 三、项目详情 首页 创建一个空的笔记本列表 mNotebookList。使用该列表和指定的布局资源 item_notebook 创建…...

根据Vue对比来深入学习React 下 props 组件传值 插槽 样式操作 hooks 高阶组件 性能优化

文章目录 函数组件的特点props组件间的传值父传子看上例子传父兄弟组件传值祖先组件传值 插槽基础插槽具名插槽作用域插槽 样式操作**CSS Modules** 生命周期useRef常用hookuseStateuseEffectuseContextuseReduceruseMemouseCallback 高阶组件什么时候使用 react性能问题和优化…...

HTML(六)超链接

HTML讲解&#xff08;一&#xff09;body部分_html body-CSDN博客 <!DOCTYPE html> <html><head><meta charset"UTF-8" /><title>title</title> </head><body><a href"https://blog.csdn.net/2301_8034953…...

【Coroutines】Implement Lua Coroutine by Kotlin - 2

Last Chapter Link 文章目录 Symmetric CoroutinesNon-Symmetric Coroutine SampleSymmetric Coroutine SampleHow to Implement Symmetric CoroutinesWonderful TricksCode DesignTail Recursion OptimizationFull Sources Symmetric Coroutines in last blog, we have talk…...

java计算机毕设课设—扫雷游戏(附源码、文章、相关截图、部署视频)

这是什么系统&#xff1f; 资源获取方式再最下方&#xff08;本次10月份活动福利&#xff0c;免费提供下载&#xff0c;自行到对应的方式1下载&#xff0c;csdn的0积分下载&#xff09; java计算机毕设课设—扫雷游戏(附源码、文章、相关截图、部署视频) 基于Java的扫雷游戏…...

AndroidLogger 使用问题

Q1&#xff1a;解压zip后&#xff0c;启动Notepad未看到AndroidLogger工具栏 请检查plugins下安装位置是否正确&#xff0c;必须与下图一致&#xff0c;再确认Notepad 是否为 x64 &#xff1f; Q2&#xff1a;使用 adb 可以显示已连接&#xff0c;但是获取不到日志 暂时不确定问…...

数据库常见面试

8道面试题 目录 目录 7道面试题 1.怎样进行sql优化 4、group by优化 5、limit优化 6、count优化 7、update优化 2.。怎样查看sql执行情况呢(哪个关键字)&#xff0c;说说你对这个关键字的认识 4) possible_key&#xff1a; 5) key 3.说说你对innodb和 myisam的理解 …...

boxplot 绘制箱线图,添加数据点

先看效果图 import matplotlib.pyplot as plt #! 解决不显示的问题&#xff1a;中文设置为宋体格式 plt.rcParams[font.family] ["Times New Roman", SimSun]def plot_boxplot(data_list, out_file, x_custom_labels):# 画图fig, ax plt.subplots(figsize(90, 6…...

用sdkman管理多个jdk切换

前言 最近项目前后端进行升级&#xff0c;需要在jdk8和jdk17两个版本切换。最简单的是通过手动切换&#xff0c;但切换过程太繁琐&#xff0c;修改环境变量&#xff0c;达到切换目的。于是尝试其它解决方案&#xff0c;最终确实使用sdkman工具。 sdkman 是一款面向Java开发者的…...

【AIGC】ChatGPT提示词Prompt高效编写模式:结构化Prompt、提示词生成器与单样本/少样本提示

&#x1f4af;前言 在如今AI技术迅猛发展的背景下&#xff0c;尽管像ChatGPT这样的大型语言模型具备强大的生成能力&#xff0c;但它们的输出质量有时仍难以完全满足我们的预期。为了让ChatGPT生成更加准确、可靠的内容&#xff0c;掌握高效的Prompt编写技巧变得尤为重要。本文…...

反调式实战(有道翻译窗口弹出)

1.添加脚本断点实现源码获取 2.Function构造器构造debugger 因为是窗口被弹出的情况&#xff0c;所以window.closefunction()构造debugger。 3.定位到影响弹出的JavaScript代码片段 反调试思想&#xff1a;置空和替换&#xff0c;所以将其JavaScript进行注释或者删除。 这里主…...

verilog端口使用注意事项

下图存在组合逻辑反馈环&#xff0c;即组合逻辑的输出反馈到输入(赋值的左右2边存在相同的信号)&#xff0c;此种情况会造成系统不稳定。比如在data_in20的情况下&#xff0c;在data_out0 时候&#xff0c;输出的数据会反馈到输入&#xff0c;输入再输出&#xff0c;从而造成不…...

Docker常用命令大全汇总

Docker是一种流行的容器化平台,可以在一个独立的、隔离的环境中构建、部署和运行应用程序。了解Docker常用命令可以帮助我们更高效地管理容器,快速开发和部署应用。本文将整理一系列Docker的常用命令,便于日常使用和学习。 1 Docker基础命令 1.1 启动/停止/重启docker # …...

Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动

一、前言说明 在2011版本的gb28181协议中&#xff0c;拉取视频流只要求udp方式&#xff0c;从2016开始要求新增支持tcp被动和tcp主动两种方式&#xff0c;udp理论上会丢包的&#xff0c;所以实际使用过程可能会出现画面花屏的情况&#xff0c;而tcp肯定不丢包&#xff0c;起码…...

基于Uniapp开发HarmonyOS 5.0旅游应用技术实践

一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架&#xff0c;支持"一次开发&#xff0c;多端部署"&#xff0c;可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务&#xff0c;为旅游应用带来&#xf…...

五年级数学知识边界总结思考-下册

目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解&#xff1a;由来、作用与意义**一、知识点核心内容****二、知识点的由来&#xff1a;从生活实践到数学抽象****三、知识的作用&#xff1a;解决实际问题的工具****四、学习的意义&#xff1a;培养核心素养…...

第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词

Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵&#xff0c;其中每行&#xff0c;每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid&#xff0c;其中有多少个 3 3 的 “幻方” 子矩阵&am…...

Spring数据访问模块设计

前面我们已经完成了IoC和web模块的设计&#xff0c;聪明的码友立马就知道了&#xff0c;该到数据访问模块了&#xff0c;要不就这俩玩个6啊&#xff0c;查库势在必行&#xff0c;至此&#xff0c;它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据&#xff08;数据库、No…...

docker 部署发现spring.profiles.active 问题

报错&#xff1a; org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...

python报错No module named ‘tensorflow.keras‘

是由于不同版本的tensorflow下的keras所在的路径不同&#xff0c;结合所安装的tensorflow的目录结构修改from语句即可。 原语句&#xff1a; from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后&#xff1a; from tensorflow.python.keras.lay…...

Scrapy-Redis分布式爬虫架构的可扩展性与容错性增强:基于微服务与容器化的解决方案

在大数据时代&#xff0c;海量数据的采集与处理成为企业和研究机构获取信息的关键环节。Scrapy-Redis作为一种经典的分布式爬虫架构&#xff0c;在处理大规模数据抓取任务时展现出强大的能力。然而&#xff0c;随着业务规模的不断扩大和数据抓取需求的日益复杂&#xff0c;传统…...

在 Spring Boot 项目里,MYSQL中json类型字段使用

前言&#xff1a; 因为程序特殊需求导致&#xff0c;需要mysql数据库存储json类型数据&#xff0c;因此记录一下使用流程 1.java实体中新增字段 private List<User> users 2.增加mybatis-plus注解 TableField(typeHandler FastjsonTypeHandler.class) private Lis…...

Ubuntu系统多网卡多相机IP设置方法

目录 1、硬件情况 2、如何设置网卡和相机IP 2.1 万兆网卡连接交换机&#xff0c;交换机再连相机 2.1.1 网卡设置 2.1.2 相机设置 2.3 万兆网卡直连相机 1、硬件情况 2个网卡n个相机 电脑系统信息&#xff0c;系统版本&#xff1a;Ubuntu22.04.5 LTS&#xff1b;内核版本…...