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

C++设计模式(单例模式)

一、介绍

1.动机

在软件系统中,经常有这样一些特殊的类,必须保证它们在系统中只存在一个实例,才能确保它们的逻辑正确性、以及良好的效率。

如何绕过常规的构造器,提供一种机制来保证一个类只有一个实例?

这应该是类设计者的责任,而不是使用者的责任。

 

2.定义

保证一个类仅有一个实例,并提供一个该实例的全局访问点。——GOF

 

3.结构图

 

4b56f1421b19494aac107f7cc9eb0b5d.jpeg

 

4.要点总结

  • Singleton模式中的实例构造器可以设置为protected以允许子类派生。
  • Singleton模式一般不支持拷贝构造函数和Clone接口,因为这有可能导致多个对象实例,与Singleton模式的初衷违背。
  • 如何实现多线程环境下安全的Singleton?注意对双检查锁的正确实现。

 

二、单例模式

1.概念

单例模式的核心在于类自身负责创建自己的唯一实例,并提供一个静态方法来获取这个实例,从而防止外部代码创建多个实例。

①单例模式的优点:

  • 节省资源,避免频繁创建和销毁对象。
  • 方便控制资源的使用。
  • 维护数据的一致性。

②单例模式的缺点:

  • 在多线程环境下,需要考虑线程安全问题。
  • 若使用锁机制可能会影响性能。

 

2.实现要点

单例模式的实现要点:

  • 私有化构造函数:防止在外部通过构造函数直接创建对象。
  • 禁用拷贝构造和赋值运算符:防止通过拷贝构造和赋值操作创建多个对象。
  • 静态变量:存储类的唯一实例。
  • 公有静态方法:提供一个全局访问点来获取这个实例。

单例模式分为饿汉式和懒汉式。

 

3.饿汉式

在程序启动时立即创建实例,因此本身是线程安全的。但无论是否使用实例,都会立即创建,可能导致资源浪费。

饿汉式单例:

class Singleton {
private:static Singleton* pSingleton;Singleton() {cout << "Singleton()" << endl;}~Singleton() {cout << "~Singleton()" << endl;}public:Singleton(const Singleton&) = delete;  //禁用拷贝构造函数Singleton& operator=(const Singleton&) = delete;  //禁用赋值运算符static Singleton* getInstance() {return pSingleton;}static void deleteInstance() {  //用于删除实例cout << "deleteInstance()" << endl;if (pSingleton) {delete pSingleton;pSingleton = nullptr;}}
};
Singleton* Singleton::pSingleton = new Singleton();
//直接创建实例

测试:

Singleton* s1 = Singleton::getInstance();
Singleton* s2 = Singleton::getInstance();
cout << s1 << endl;
cout << s2 << endl;
Singleton::deleteInstance();

 

4.懒汉式

程序启动时实例并不存在,只有在需要使用时才会创建实例,这种方式要考虑线程安全的问题。

①使用静态局部变量实现懒汉式单例

class Singleton {
private:Singleton() {cout << "Singleton()" << endl;}~Singleton() {cout << "~Singleton()" << endl;}public:static Singleton* getInstance() {static Singleton instance;  //静态局部变量return &instance;}Singleton(const Singleton&) = delete;Singleton& operator=(const Singleton&) = delete;};

静态局部变量存储在静态存储区,只在当前函数内有效,其它函数无法访问。

静态局部变量只在第一次调用时初始化,生命周期从第一次初始化开始,到程序结束为止。

 

②使用双检查锁实现懒汉式单例

class Singleton {
private:static mutex mtx;  //互斥锁static atomic<shared_ptr<Singleton>> pSingleton;  //原子智能指针Singleton() {cout << "Singleton()" << endl;}public:~Singleton() {  //设置为公有,智能指针要调用cout << "~Singleton()" << endl;}Singleton(const Singleton&) = delete;Singleton& operator=(const Singleton&) = delete;static shared_ptr<Singleton> getInstance() {shared_ptr<Singleton> ptr = pSingleton.load();  //读取if (!ptr) {  //第一次检查unique_lock<mutex> amtx(mtx);ptr = pSingleton.load();  //读取if (!ptr) {  //第二次检查ptr = shared_ptr<Singleton>(new Singleton);pSingleton.store(ptr);  //存储}}return ptr;}
};
mutex Singleton::mtx;
atomic<shared_ptr<Singleton>> Singleton::pSingleton = nullptr;

atomic的load和store成员函数用于以原子方式读取和存储原子变量。它们可以接受一个memory_order参数,该参数用于指定在内存模型中操作的内存顺序。如果不提供则会默认使用memory_order_seq_cst,这是最严格的内存顺序,它保证了读取操作的顺序性和内存可见性。

 

③使用call_once实现懒汉式单例

class Singleton {
private:static once_flag flag;  //用于标记static shared_ptr<Singleton> pSingleton;  //智能指针Singleton() {cout << "Singleton()" << endl;}public:~Singleton() {  //设置为公有,智能指针要调用cout << "~Singleton()" << endl;}Singleton(const Singleton&) = delete;Singleton& operator=(const Singleton&) = delete;static shared_ptr<Singleton> getInstance() {call_once(flag, [] {  //最多调用一次pSingleton = shared_ptr<Singleton>(new Singleton);});return pSingleton;}
};
once_flag Singleton::flag;
shared_ptr<Singleton> Singleton::pSingleton = nullptr;

call_once可以让函数或代码块在多线程环境中最多只被执行一次。

 

 

相关文章:

C++设计模式(单例模式)

一、介绍 1.动机 在软件系统中&#xff0c;经常有这样一些特殊的类&#xff0c;必须保证它们在系统中只存在一个实例&#xff0c;才能确保它们的逻辑正确性、以及良好的效率。 如何绕过常规的构造器&#xff0c;提供一种机制来保证一个类只有一个实例? 这应该是类设计者的…...

前端---CSS(部分用法)

HTML画页面--》这个页面就是页面上需要的元素罗列起来&#xff0c;但是页面效果很差&#xff0c;不好看&#xff0c;为了让页面好看&#xff0c;为了修饰页面---》CSS CSS的作用&#xff1a;修饰HTML页面 用了CSS之后&#xff0c;样式和元素本身做到了分离的效果。---》降低了代…...

2024年最新版Java八股文复习

最新版本Java八股文复习&#xff0c;每天更新一篇&#xff0c;博主正在持续努力更新中~~~ 一、Java基础篇1、怎么理解面向对象&#xff1f;简单说说封装、继承、多态三大特性&#xff1f;2、多态体现在哪几个方面&#xff1f;3、面向对象的设计原则你知道有哪些吗&#xff1f;4…...

计算机毕业设计Hadoop+Spark音乐推荐系统 音乐预测系统 音乐可视化大屏 音乐爬虫 HDFS hive数据仓库 机器学习 深度学习 大数据毕业设计

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…...

MyBatis高级扩展

一、Mapper批量映射优化: 1.需求: Mapper 配置文件很多时&#xff0c;在全局配置文件中一个一个注册太麻烦&#xff0c;希望有一个办法能够一劳永逸 2.配置方式: Mybatis允许在指定Mapper映射文件时&#xff0c;只指定其所在的包: <mappers><package name"c…...

代码美学2:MATLAB制作渐变色

效果&#xff1a; %代码美学&#xff1a;MATLAB制作渐变色 % 创建一个10x10的矩阵来表示热力图的数据 data reshape(1:100, [10, 10]);% 创建热力图 figure; imagesc(data);% 设置颜色映射为“cool” colormap(cool);% 在热力图上添加边框 axis on; grid on;% 设置热力图的颜色…...

浅谈- “ 变量中 无符号 与 有符号 的 值转换 ”

在同一个表达式中&#xff0c;若同时出现 无符号变量 与 有符号变量 &#xff1a; 1、都转换为无符号类型&#xff1a;&#xff08;注&#xff1a;2^324294967296&#xff09;即unsigned int 的最大值 2、然后再运行表达式 实例&#xff1a; #include <stdio.h>char fun(…...

【AI绘画】Midjourney进阶:色调详解(上)

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: AI绘画 | Midjourney 文章目录 &#x1f4af;前言&#x1f4af;Midjourney中的色彩控制为什么要控制色彩&#xff1f;为什么要在Midjourney中控制色彩&#xff1f; &#x1f4af;色调白色调淡色调明色调 &#x1f4af…...

代码管理之Gitlab

文章目录 Git基础概述场景本地修改未提交&#xff0c;拉取远程代码修改提交本地&#xff0c;远程已有新提交 GitIDEA引入Git拉取仓库代码最后位置 Git基础 概述 workspace 工作区&#xff1a;本地电脑上看到的目录&#xff1b; repository 本地仓库&#xff1a;就是工作区中隐…...

防御网络攻击的创新策略

关键要点 ● 了解各种类型的网络攻击对于组织加强防御至关重要。 ● 制定敏捷的网络安全策略可帮助企业快速应对新出现的威胁。 ● 跨行业协作和威胁情报共享可以增强整体安全性。 网络攻击威胁日益严重 网络攻击的数量和复杂程度急剧增加&#xff0c;对全球组织构成了重大…...

C++软件设计模式之组合模式概述

组合模式&#xff08;Composite Pattern&#xff09;是C软件设计模式中的一种&#xff0c;主要用于解决对象的层次结构问题。它允许你将对象组合成树形结构来表示“部分-整体”的层次结构&#xff0c;使得客户端可以统一地处理单个对象和组合对象。 主要用于解决的问题&#x…...

利用HTML5和CSS来实现一个漂亮的表格样式

利用HTML5和CSS来实现一个漂亮的表格样式 第一步&#xff1a;创建HTML结构第二步&#xff1a;添加CSS样式第三步&#xff1a;响应式设计第四步&#xff1a;加入交互效果 第一步&#xff1a;创建HTML结构 我们将用HTML创建一个基本的表格结构。代码如下&#xff1a; <!DOCT…...

Vivado程序固化到Flash

在上板调试FPGA时&#xff0c;通常使用JTAG接口下载程序到FPGA芯片中&#xff0c;FPGA本身是基于RAM工艺的器件&#xff0c;因此掉电后会丢失芯片内的程序&#xff0c;需要重新烧写程序。但是当程序需要投入使用时不能每一次都使用JTAG接口下载程序&#xff0c;一般FPGA的外围会…...

HCIA笔记3--TCP-UDP-交换机工作原理

1. tcp协议 可靠的连接 1.1 报文格式 1.2 三次握手 1.3 四次挥手 为什么TIME_WAIT需要2MSL的等待时间&#xff1f; &#xff08;a&#xff09; 为了实现可靠的关闭 &#xff08;b&#xff09;为了让过期的报文在网络上消失 对于(a), 假设host发给server的last ack丢了。 ser…...

计算机网络的功能

目录 信息交换 资源共享 分布式处理 可靠性增强 集中管理 信息交换 计算机网络最基本的功能之一是允许不同设备之间的数据通信。这包括电子邮件的发送和接收、即时消息的传递、文件传输等。通过网络&#xff0c;用户可以轻松地与全球各地的其他人进行沟通和协作。 信息交…...

Redis设计与实现第14章 -- 服务器 总结(命令执行器 serverCron函数 初始化)

14.1 命令请求的执行过程 一个命令请求从发送到获得回复的过程中&#xff0c;客户端和服务器都需要完成一系列操作。 14.1.1 发送命令请求 当用户在客户端中输入一个命令请求的时候&#xff0c;客户端会把这个命令请求转换为协议格式&#xff0c;然后通过连接到服务器的套接字…...

多输入多输出 | Matlab实现TCN-GRU时间卷积神经网络结合门控循环单元多输入多输出预测

多输入多输出 | Matlab实现TCN-GRU时间卷积神经网络结合门控循环单元多输入多输出预测 目录 多输入多输出 | Matlab实现TCN-GRU时间卷积神经网络结合门控循环单元多输入多输出预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 多输入多输出 | Matlab实现TCN-GRU时间卷积…...

windows安全中心,永久卸载工具分享

使用方法 2024Goby红队版工具分享&#xff0c;附2024年漏洞POC下载 下载链接&#xff1a; https://pan.quark.cn/s/4fc2712a2afc一路回车&#xff0c;选项Y即可 耐心等待几秒种&#xff0c;自动重启 此时打开windows安全中心&#xff0c;已经完全不能使用了&#xff0c;响应…...

《安富莱嵌入式周报》第346期:开源2GHz带宽,12bit分辨率,3.2Gsps采样率示波,开源固件安全分析器, 开源口袋电源,开源健康测量,FreeCAD

周报汇总地址&#xff1a;嵌入式周报 - uCOS & uCGUI & emWin & embOS & TouchGFX & ThreadX - 硬汉嵌入式论坛 - Powered by Discuz! 视频&#xff1a; https://www.bilibili.com/video/BV1TYBhYKECK/ 《安富莱嵌入式周报》第346期&#xff1a;开源2GHz带…...

Apache OFBiz xmlrpc XXE漏洞(CVE-2018-8033)

目录 1、漏洞描述 2、EXP下载地址 3、EXP利用 1、漏洞描述 Apache OFBiz是一套企业资源计划&#xff08;ERP&#xff09;系统。它提供了广泛的功能&#xff0c;包括销售、采购、库存、财务、CRM等。 Apache OFBiz还具有灵活的架构和可扩展性&#xff0c;允许用户根据业务需求…...

从零开始学习C++ -- 基础知识

C入门基础1.C的第一个程序2.命名空间2.1 namespace的价值2.2 namespace的定义2.3命名空间使用3.C输入&输出4.缺省参数5.函数重载6.引用6.1引用的概念和定义6.2引用的特性6.3引用的使用6.4const引用6.5指针和引用的关系7.inline8.nullptr1.C的第一个程序 #include <iost…...

TAICHI-flet终极排障指南:从新手到高手的完整解决方案

TAICHI-flet终极排障指南&#xff1a;从新手到高手的完整解决方案 【免费下载链接】TAICHI-flet 基于flet的一款windows桌面应用&#xff0c;实现了浏览图片、音乐、小说、漫画、各种资源的功能。 项目地址: https://gitcode.com/GitHub_Trending/ta/TAICHI-flet TAICHI…...

QLVideo终极指南:让macOS Finder完美预览所有视频格式

QLVideo终极指南&#xff1a;让macOS Finder完美预览所有视频格式 【免费下载链接】QuickLookVideo This package allows macOS Finder to display thumbnails, static QuickLook previews, cover art and metadata for most types of video files. 项目地址: https://gitcod…...

5分钟掌握游戏高清截图秘诀:SRWE窗口分辨率自定义完整教程

5分钟掌握游戏高清截图秘诀&#xff1a;SRWE窗口分辨率自定义完整教程 【免费下载链接】SRWE Simple Runtime Window Editor 项目地址: https://gitcode.com/gh_mirrors/sr/SRWE 你是否曾梦想为心爱的游戏角色拍摄一张高清壁纸&#xff0c;却发现游戏分辨率选项有限&…...

3分钟掌握图片比对:PicQuickCompare让你高效发现视觉差异

3分钟掌握图片比对&#xff1a;PicQuickCompare让你高效发现视觉差异 【免费下载链接】PicQuickCompare Compare two pictures quickly 项目地址: https://gitcode.com/gh_mirrors/pi/PicQuickCompare PicQuickCompare是一款专为快速图片比对而设计的轻量级工具&#xf…...

使用Dependency Check命令行工具高效检测Java项目中的安全漏洞

1. 为什么Java开发者需要关注依赖库安全&#xff1f; 如果你是一名Java开发者&#xff0c;可能经常遇到这样的情况&#xff1a;项目运行得好好的&#xff0c;突然某天系统被入侵了&#xff0c;排查半天才发现是某个第三方库存在安全漏洞。这种情况在现实开发中并不少见&#xf…...

阅读书源校验工具verifyBookSource v2.0避坑指南:如何避免无效书源和重复书源

verifyBookSource v2.0 高效书源管理实战&#xff1a;从校验到优化的完整指南 在数字阅读日益普及的今天&#xff0c;一个优质的书源库能显著提升阅读体验。然而&#xff0c;面对海量书源&#xff0c;如何快速筛选有效内容、剔除重复资源&#xff0c;成为许多阅读爱好者的痛点。…...

SCI期刊AI率要求越来越严:一二区5%以下该怎么降

SCI一二区期刊AI率卡到5%以下&#xff0c;我的论文差点废了——后来这么救回来的 2026年开年&#xff0c;身边三个同学的SCI投稿被拒&#xff0c;理由都一样&#xff1a;AI-generated content detected。不是内容不行&#xff0c;是AI率没过关。 我的判断很直接&#xff1a;S…...

STC-50kg

【广州兰瑟★电子-杨工】提供的STC-50kg 是美国威世世铨&#xff08;Vishay Celtron&#xff09;旗下一款经典的 S 型拉压双向称重 / 测力传感器&#xff0c;量程 50 公斤 (50kgf / 490N)。 一、核心参数&#xff08;标准型&#xff09; 量程&#xff1a;50 kg (拉力 / 压力双向…...

WordPress主题开发实战:从零开始搭建你的第一个自定义主题(2024最新版)

WordPress主题开发实战&#xff1a;从零开始搭建你的第一个自定义主题&#xff08;2024最新版&#xff09; 如果你正准备踏入WordPress主题开发的世界&#xff0c;这篇文章将带你从零开始构建一个完整的自定义主题。不同于简单的仿制或修改现有主题&#xff0c;我们将深入探讨如…...