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

C++单例模式

文章目录

  • 1、什么是单例
  • 2、一个好的单例应该具备的条件
  • 3、懒汉模式与饿汉模式
  • 4、单例实现:线程安全、内存安全的懒汉式单例(基于C++11的智能指针和互斥锁)

1、什么是单例

单例 Singleton 是设计模式的一种,其特点是只提供唯一一个类的实例,具有全局变量的特点,在任何位置都可以通过接口获取到那个唯一实例。

具体应用场景如:

  • 设备管理器。系统中可能有多个设备,但是只有一个设备管理器,用于管理设备驱动;

  • 数据池。用来缓存数据的数据结构,需要在一处写,多处读取或者多处写,多处读取。

2、一个好的单例应该具备的条件

  • 全局只有一个实例:static 特性,同时禁止用户自己声明并定义实例(把构造函数设为 private)
  • 用户通过接口获取实例:使用 static 类成员函数
  • 禁止赋值和拷贝
  • 线程安全

3、懒汉模式与饿汉模式

  • 懒汉模式:
    • 时间换空间;
    • 故名思义,不到万不得已就不会去实例化对象,在第一次用到类实例的时候才会去实例化对象;
    • 多线程情况下会存在线程安全问题,需要加互斥锁进行防护。
  • 饿汉模式:
    • 空间换时间;
    • 在单例类定义的时候就进行实例化对象,当需要使用时只要通过接口函数直接获取对象。

4、单例实现:线程安全、内存安全的懒汉式单例(基于C++11的智能指针和互斥锁)

#include <iostream>
#include <memory>
#include <mutex>class Singleton {
public:~Singleton() {std::cout << "destructor called!" << std::endl;}Singleton(Singleton&) = delete;                  // copy constructor can't be calledSingleton& operator=(const Singleton&) = delete; // assignment operator can't be calledstatic std::shared_ptr<Singleton> getInstance() {// 双重锁检测if (m_pInstance == nullptr) {std::lock_guard<std::mutex> lk(m_mutex);if (m_pInstance == nullptr) {m_pInstance = std::shared_ptr<Singleton>(new Singleton);}}return m_pInstance;}private:Singleton() {std::cout << "constructor called!" << std::endl;}private:static std::shared_ptr<Singleton> m_pInstance;static std::mutex m_mutex;
};// initialization static variables out of class
std::shared_ptr<Singleton> Singleton::m_pInstance = nullptr;
std::mutex Singleton::m_mutex;int main() {std::shared_ptr<Singleton> instance1 = Singleton::getInstance();std::shared_ptr<Singleton> instance2 = Singleton::getInstance();return 0;
}

运行结果:

PS E:\Code\VSCode\Demo\build> ."E:/Code/VSCode/Demo/build/main.exe"
constructor called!
destructor called!
  • 基于 shared_ptr,用了C++比较倡导的 RAII 思想,即用对象管理资源。当 shared_ptr 析构的时候,new 出来的对象也会被 delete 掉,此避免内存泄漏。
  • 加了锁,使用互斥量来达到线程安全。这里使用了两个 if 判断语句的技术称为双检锁,其好处是,只有判断指针为空的时候才加锁,避免每次调用 get_instance 的方法都加锁,毕竟锁的开销还是有点大的。

不足之处在于: 使用智能指针会要求用户也得使用智能指针,非必要不应该提出这种约束;使用锁也有开销,并且在某些平台(与编译器和指令集架构有关),双检锁会失效!

相关文章:

C++单例模式

文章目录 1、什么是单例2、一个好的单例应该具备的条件3、懒汉模式与饿汉模式4、单例实现&#xff1a;线程安全、内存安全的懒汉式单例&#xff08;基于C11的智能指针和互斥锁&#xff09; 1、什么是单例 单例 Singleton 是设计模式的一种&#xff0c;其特点是只提供唯一一个类…...

C++ 析构函数

析构函数 析构函数于构造函数相对应&#xff0c;构造函数是对象创建的时候自动调用的&#xff0c;而析构函数就是对象在销毁的时候自动调用的 特点&#xff1a; 1&#xff09;构造函数可以有多个来构成重载&#xff0c;但析构函数只能有一个&#xff0c;不能构成重载 2&…...

CSS——字体选择

在网页设计和开发中&#xff0c;字体选择是一个非常重要的因素。字体不仅仅是文字的表现形式&#xff0c;它们还能够传达出一种特定的情感和风格。在CSS中&#xff0c;我们可以通过使用字体代码来定义网页中使用的字体。 CSS提供了一种简单而灵活的方式来设置字体。通过使用fo…...

SpringBoot自动装配及run方法原理探究

自动装配 1、pom.xml spring-boot-dependencies&#xff1a;核心依赖在父工程中&#xff01;我们在写或者引入一些SpringBoot依赖的时候&#xff0c;不需要指定版本&#xff0c;就因为有这些版本仓库 1.1 其中它主要是依赖一个父工程&#xff0c;作用是管理项目的资源过滤及…...

Mybatis实现JsonObject对象与JSON之间交互

项目中使用PostGresql数据库进行数据存储&#xff0c;表中某字段为Json类型&#xff0c;用于存储Json格式数据。PG数据库能够直接存储Json算是一大特色&#xff0c;很多特定情境下使用直接存储Json字段数据能够大量节省开发时间&#xff0c;提高后台数据查询和转换效率。 1、基…...

spring boot 集成 jetcache【基础篇:@Cached、@CreateCache、@CacheRefresh】

手打不易&#xff0c;如果转摘&#xff0c;请注明出处&#xff01; 注明原文&#xff1a;https://zhangxiaofan.blog.csdn.net/article/details/129832925 目录 前言 版本 配置通用说明 项目结构 代码 启动类 实体类 基础使用——增删改查&#xff08;Cached、CacheInv…...

个人对前后端分离的一些看法

内容简介&#xff1a;前端开发过程中能完全不依赖后端的才是真正的前后端分离指的是工作过程中&#xff0c;前端的的代码中往往会掺杂一些后端的逻辑。后端返回了一个json对象 前端开发过程中能完全不依赖后端的才是真正的前后端分离 指的是工作过程中&#xff0c;前端的的代码…...

TailWindCss 在Hbuilderx中使用

基于这个插件 weapp-tailwindcss 地址 本次说明基于HbuilderX 创建的项目非CLI 安装步骤按照文档走&#xff0c;先安装上几个依赖。然后是几个配置文件 tailwind-input.css tailwind的css文件用来引入到app.vue /* #ifdef H5 */ tailwind base; /* 如果是小程序的话&#x…...

Unity导入图片时,通过设置属性快速实现资源的压缩

是在学习tilemap绘制世界地图的时候发现的这个功能。 之前一直只是粗略的知道这部分是对应图片资源的压缩的。比如Compression是指的压缩质量&#xff0c;想要完全不压缩就设置None&#xff0c;会导致图片资源会大一些。 在我的例子工程中&#xff0c;其他图片资源的尺寸都是6…...

AlmaLinux 9 安装 Go 1.20

AlmaLinux 9 安装 Golang 1.20 1. 下载 go 安装包2. 安装 go3. 配置环境变量4. 确认 go 版本 1. 下载 go 安装包 访问 https://go.dev/dl/&#xff0c;下载你想安装的版本&#xff0c;比如 go1.20.7.linux-amd64.tar.gz&#xff0c; 2. 安装 go (可选)删除旧版本&#xff0c;…...

【Docker】数据库动态授权组件在Kubernetes集群下的测试过程记录

目录 背景 组件原理 测试设计 环境 测试脚本 脚本build为linux可执行文件 镜像构建 Dockerfile Docker build 镜像有效性验证 总结 资料获取方法 背景 我们都知道出于安全性考虑&#xff0c;生产环境的权限一般都是要做最小化控制&#xff0c;尤其是数据库的操作授…...

数据结构【第3章】——线性表

线性表的定义 线性表&#xff1a;零个或多个数据元素的有限序列。 1&#xff09;线性表是一个序列。即元素之间是有顺序的&#xff0c;若元素存在多个&#xff0c;则第一个元素无前驱&#xff0c;最后一个元素无后继&#xff0c;其他每个元素都有且只有一个前驱和后继。 2&a…...

MySql之分库分表

数据库瓶颈 不管是IO瓶颈还是CPU瓶颈&#xff0c;最终都会导致数据库的活跃连接数增加&#xff0c;进而逼近甚至达到数据库可承载的活跃连接数的阈值。在业务service来看&#xff0c; 就是可用数据库连接少甚至无连接可用&#xff0c;接下来就可以想象了&#xff08;并发量、吞…...

数据结构—图的遍历

6.3图的遍历 遍历定义&#xff1a; ​ 从已给的连通图中某一顶点出发&#xff0c;沿着一些边访问遍历图中所有的顶点&#xff0c;且使每个顶点仅被访问一次&#xff0c;就叫作图的遍历&#xff0c;它是图的基本运算。 遍历实质&#xff1a;找每个顶点的邻接点的过程。 图的…...

MySQL主从复制基于二进制日志的高可用架构指南

前言 在现代数据库架构中&#xff0c;MySQL主从复制技术扮演着重要角色。它不仅可以提升数据库性能和可扩展性&#xff0c;还赋予系统卓越的高可用性和灾难恢复能力。本文将深入剖析MySQL主从复制的内部机制&#xff0c;同时通过一个实际案例&#xff0c;展示其在实际场景中的…...

RestTemplate HTTPS请求忽略SSL证书

问题描述 使用RestTemplate发送HTTPS请求的时候&#xff0c;出现了这样的一个问题&#xff1a; sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification …...

Jenkins触发器时间、次数设定

触发器触发条件介绍 触发器触发条件公式&#xff1a;由5颗星组成 * * * * * 分别代表&#xff1a;分钟(0-59) 小时(0-23) 日期(1-31) 月份(1-12) 星期(0-6) 企业项目中常用场景介绍 场景1&#xff1a;接口脚本部分测试通过&#xff0c;部分还在进行&#xff0c;回归测试脚本执行…...

kafka partition的数据文件(offffset,MessageSize,data)

partition中的每条Message包含了以下三个属性&#xff1a; offset&#xff0c;MessageSize&#xff0c;data&#xff0c;其中offset表示Message在这个partition中的偏移量&#xff0c;offset不是该Message在partition数据文件中的实际存储位置&#xff0c;而是逻辑上一个值&…...

htnl根据轮播图图片切换背景色

htnl根据轮播图图片切换背景色 <!DOCTYPE html> <html><head><meta charset"UTF-8"><title>轮播图示例</title><link rel"stylesheet" href"https://cdn.jsdelivr.net/npm/swiper10/swiper-bundle.min.css&q…...

gpu-manager安装及测试

提示&#xff1a;GPU-manager安装为主部分内容做了升级开箱即用&#xff0c;有用请点收藏❤抱拳 文章目录 前言一、约束条件二、使用步骤1.下载镜像1.1 查看当前虚拟机的驱动类型&#xff1a; 2.部署gpu-manager3.部署gpu-admission4.修改kube-scheduler.yaml![在这里插入图片描…...

黑马Mybatis

Mybatis 表现层&#xff1a;页面展示 业务层&#xff1a;逻辑处理 持久层&#xff1a;持久数据化保存 在这里插入图片描述 Mybatis快速入门 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/6501c2109c4442118ceb6014725e48e4.png //logback.xml <?xml ver…...

Cesium1.95中高性能加载1500个点

一、基本方式&#xff1a; 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...

React---day11

14.4 react-redux第三方库 提供connect、thunk之类的函数 以获取一个banner数据为例子 store&#xff1a; 我们在使用异步的时候理应是要使用中间件的&#xff0c;但是configureStore 已经自动集成了 redux-thunk&#xff0c;注意action里面要返回函数 import { configureS…...

让回归模型不再被异常值“带跑偏“,MSE和Cauchy损失函数在噪声数据环境下的实战对比

在机器学习的回归分析中&#xff0c;损失函数的选择对模型性能具有决定性影响。均方误差&#xff08;MSE&#xff09;作为经典的损失函数&#xff0c;在处理干净数据时表现优异&#xff0c;但在面对包含异常值的噪声数据时&#xff0c;其对大误差的二次惩罚机制往往导致模型参数…...

CVE-2020-17519源码分析与漏洞复现(Flink 任意文件读取)

漏洞概览 漏洞名称&#xff1a;Apache Flink REST API 任意文件读取漏洞CVE编号&#xff1a;CVE-2020-17519CVSS评分&#xff1a;7.5影响版本&#xff1a;Apache Flink 1.11.0、1.11.1、1.11.2修复版本&#xff1a;≥ 1.11.3 或 ≥ 1.12.0漏洞类型&#xff1a;路径遍历&#x…...

Go 语言并发编程基础:无缓冲与有缓冲通道

在上一章节中&#xff0c;我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道&#xff0c;它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好&#xff0…...

MySQL JOIN 表过多的优化思路

当 MySQL 查询涉及大量表 JOIN 时&#xff0c;性能会显著下降。以下是优化思路和简易实现方法&#xff1a; 一、核心优化思路 减少 JOIN 数量 数据冗余&#xff1a;添加必要的冗余字段&#xff08;如订单表直接存储用户名&#xff09;合并表&#xff1a;将频繁关联的小表合并成…...

Caliper 负载(Workload)详细解析

Caliper 负载(Workload)详细解析 负载(Workload)是 Caliper 性能测试的核心部分,它定义了测试期间要执行的具体合约调用行为和交易模式。下面我将全面深入地讲解负载的各个方面。 一、负载模块基本结构 一个典型的负载模块(如 workload.js)包含以下基本结构: use strict;/…...

tomcat入门

1 tomcat 是什么 apache开发的web服务器可以为java web程序提供运行环境tomcat是一款高效&#xff0c;稳定&#xff0c;易于使用的web服务器tomcathttp服务器Servlet服务器 2 tomcat 目录介绍 -bin #存放tomcat的脚本 -conf #存放tomcat的配置文件 ---catalina.policy #to…...

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;内核版本…...