C++练级计划->《单例模式》懒汉和饿汉
目录
单例模式是什么?
单例模式的应用:
饿汉单例模式:
1.实现:
2.理解:
懒汉单例模式:
1.实现:
2.理解:
懒汉和饿汉的优缺点
饿汉模式的优点:
饿汉模式的缺点:
懒汉模式的优点:
懒汉模式的缺点:
单例模式是什么?
单例模式顾名思义:单个实例,就是说一个类只能实例化出一个对象。通常都是作为全局对象,要让所有人都能访问,但是只有一份。
单例模式的应用:
日志记录:通常在开发过程中是多人的,那就会有很多人来写日志。这时候就需要一个日志记录器,用于记录所有模块的日志信息,所以这个记录器应该是针对所有人的,并且为了避免重复,所以使用单例模式
相似的还有配置管理,连接池管理,全局状态管理
在多线程下的线程安全对象。有些对象需要确保只有一个实例被多个线程共享(多个线程使用一个对象)。结合锁的使用,可以保证这个单独对象在多线程下的安全性和一致性。
饿汉单例模式:
1.实现:
单例模式的使用方式就是:这个对象初始化完后,只能通过一个静态接口获取,并且要把构造函数和赋值构造拷贝构造都放入私有中。如下代码:
class Singleton{public:static Singleton* GetInstance() //通过调用GetInstance() 在类外获得实例{ return &_slt; //返回这个实例的地址}void print() //输出实例的数据{cout << _x << " " << _y << endl;for (auto e : _vect){cout << e << " ";}cout << endl;}void Add_Vect(int n) //对实例的Vector进行尾插{_vect.push_back(n);}private:int _x;int _y;vector<int>_vect;static Singleton _slt; //类内声明//因为要实现单例类(全局只能有一个对象,因此要将构造函数私有化否则可以在类外随便创建)Singleton(int x = 1, int y = 1, const vector<int>& v = { 1,2,3,4,5 }):_x(x), _y(y), _vect(v){}//禁用拷贝构造和赋值重载Singleton(const Singleton& hs) = delete;Singleton& operator=(const Singleton& hs) = delete;};//类外初始化Singleton Singleton::_slt(2, 2,{ 4,5,6 });//测试懒汉void Test01(){//Singleton::GetInstance()返回创建静态对象的指针Singleton::GetInstance()->print();Singleton::GetInstance()->print();cout << "对象1的地址为:" << Singleton::GetInstance() << endl;cout << "对象2的地址为:" << Singleton::GetInstance() << endl;//结果为://2 2 //4 5 6//后面两个地址是一样的(也就是返回的都是同一个实例)}
2.理解:
1.饿汉模式解释:
顾名思义:饿汉,就是一个很饿的人,只要有东西吃立马就吃了,没有任何等待的所以饿汉模式就是在还没进入main函数前就实例好的模式。
2.为什么要把三种构造函数私有化?
很显然我们要实现单例,那就不允许你在类外调用构造函数,生成这个对象,所以我们在类内就声明了这个对象,初始化时也是只能对这个对象(_slt)初始化。拷贝和赋值也是同理,我只能有一个这个对象,所以不允许你拷贝和赋值
3.然后实现的饿汉模式(对上面代码的解释)
static Singleton _slt; //类内声明我们在类内声明了这个对象,然后把三个构造函数给私有化,所以现在就只剩下这一个对象
又因为单例模式是全局给所有人使用的所以在类外初始化时是全局初始化
//类外初始化Singleton Singleton::_slt(2, 2,{ 4,5,6 });接下来要调用这个对象,只能通过先指定要调用的类然后GetInstance()找到这个单例对象。然后才能调用对应的接口。因为无法构造,且调用时只能通过接口,所以不用担心对象被修改。所以实现了单例模式
static Singleton* GetInstance() //通过调用GetInstance() 在类外获得实例{ return &_slt; //返回这个实例的地址}//Singleton::GetInstance()返回创建静态对象的指针Singleton::GetInstance()->print();Singleton::GetInstance()->print();
懒汉单例模式:
顾名思义:懒汉,就是很懒的一个人,顶级拖延症,只有必要时才会做对应的事,所以懒汉就是只有要使用这个实例时才进行创建
1.实现:
class Singleton{public:static Singleton* GetInstance() //必须定义为静态函数因为只有这样才可以不创建对象去调用它来创建对象{ //否则所有成员函数要通过对象去调用(若不设置为静态的无法创建出来对象(构造函数私有了))static Singleton slt(2, 2, {7,8,9}); //静态函数每次只会初始化一次 所以只会在第一次调用时初始化return &slt; //下次调用GetInstance()会直接返回&slt}void print(){cout << _x << " " << _y << endl;for (auto e : _vect){cout << e << " ";}cout << endl;}void Add_Vect(int n){_vect.push_back(n);}private:int _x;int _y;vector<int>_vect;//因为要实现单例类(全局只能有一个对象,因此要将构造函数私有化否则可以在类外随便创建)Singleton(int x = 1, int y = 1, const vector<int>& v = { 1,2,3,4,5 }):_x(x), _y(y), _vect(v){}//禁用拷贝构造和赋值重载Singleton(const Singleton& hs) = delete;Singleton& operator=(const Singleton& hs) = delete;};//测试懒汉void Test01(){//Singleton::GetInstance()返回创建静态对象的指针Singleton::GetInstance()->print(); Singleton::GetInstance()->print();cout << "对象1的地址为:" << Singleton::GetInstance() << endl;cout << "对象2的地址为:" << Singleton::GetInstance() << endl;//结果为:(因为调用两次所以打印两次)//2 2 //7 8 9//2 2//7 8 9//后面两个地址是一样的}
2.理解:
1.创建时机:
这里我们和饿汉不同的点就是我们把slt的初始化放到了GetInstance()里,所以只有有人调用时才会创建这个slt。
2.slt会不会重复创建:
当然不会,这里就要先理解一下静态成员:静态成员在一个对象中只会初始化一次并存入静态区中。所以不会重复创建。当然三个构造函数还是要私有化,不能让别人使用构造。
懒汉和饿汉的优缺点
饿汉模式的优点:
- 线程安全:在类加载的时候就创建实例,不存在多线程环境下的线程安全问题(还没进入主函数就创建完实例了,所以不用担心线程安全问题)。
饿汉模式的缺点:
- 可能会造成资源浪费:在程序运行过程中始终存在实例,可能会占用一定的资源。
- 不支持延迟加载:无法实现延迟加载的特性。就是说如果这个单例很大,那在开始时,可能会一直卡着,直到这个单例初始化完成。
懒汉模式的优点:
- 延迟加载:在第一次调用时才创建实例,节省资源。
- 节约内存:只有在需要时才创建实例,避免资源浪费。
懒汉模式的缺点:
- 线程安全性问题:在多线程环境下,需要额外的同步措施来保证线程安全。
- 可能存在性能问题:在第一次调用时需要进行实例化,可能会影响程序性能。
相关文章:
C++练级计划->《单例模式》懒汉和饿汉
目录 单例模式是什么? 单例模式的应用: 饿汉单例模式: 1.实现: 2.理解: 懒汉单例模式: 1.实现: 2.理解: 懒汉和饿汉的优缺点 饿汉模式的优点: 饿汉模式的缺点&a…...
SQL for XML
关系数据模型与SQL SQL for XML 模式名功能RAW返回的行作为元素,列值作为元素的属性AUTO返回表名对应节点名称的元素,每列的属性作为元素的属性输出输出,可形成简单嵌套结构EXPLICIT通过SELECT语法定义输出XML结构PATH列名或列别名作为XPAT…...
如何使用GCC手动编译stm32程序
如何不使用任何IDE(集成开发环境)编译stm32程序? 集成开发环境将编辑器、编译器、链接器、调试器等开发工具集成在一个统一的软件中,使得开发人员可以更加简单、高效地完成软件开发过程。如果我们不使用KEIL,IAR等集成开发环境,…...
在线绘制Nature Communication同款双色、四色火山图,突出感兴趣的基因
导读:火山图通常使用三种颜色分别表示显著上调,显著下调和不显著。通过为特定的数据点添加另一种颜色,可以创建双色或四色火山图,从而更直观地突出感兴趣的数据点。 《Nature Communication》文章“Molecular and functional land…...
C语言:C语言实现对MySQL数据库表增删改查功能
基础DOME可以用于学习借鉴; 具体代码 #include <stdio.h> #include <mysql.h> // mysql 文件,如果配置ok就可以直接包含这个文件//宏定义 连接MySQL必要参数 #define SERVER "localhost" //或 127.0.0.1 #define USER "roo…...
C++ 二叉搜索树(Binary Search Tree, BST)深度解析与全面指南:从基础概念到高级应用、算法优化及实战案例
🌟个人主页:落叶 🌟当前专栏: C专栏 目录 ⼆叉搜索树的概念 ⼆叉搜索树的性能分析 ⼆叉搜索树的插⼊ ⼆叉搜索树的查找 二叉搜索树中序遍历 ⼆叉搜索树的删除 cur的左节点为空的情况 cur的右节点为空的情况 左,右节点都不为…...
刷题日常(移动零,盛最多水的容器,三数之和,无重复字符的最长子串)
移动零 给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。 请注意 ,必须在不复制数组的情况下原地对数组进行操作。 俩种情况: 1.当nums[i]为0的时候 直接i 2.当nums[i]不为0的时候 此时 …...
深入了解决策树---机器学习中的经典算法
引言 决策树(Decision Tree)是一种重要的机器学习模型,以直观的分层决策方式和简单高效的特点成为分类和回归任务中广泛应用的工具。作为解释性和透明性强的算法,决策树不仅适用于小规模数据,也可作为复杂模型的基石&…...
Elasticsearch对于大数据量(上亿量级)的聚合如何实现?
大家好,我是锋哥。今天分享关于【Elasticsearch对于大数据量(上亿量级)的聚合如何实现?】面试题。希望对大家有帮助; Elasticsearch对于大数据量(上亿量级)的聚合如何实现? 1000道 …...
深度学习模型:循环神经网络(RNN)
一、引言 在深度学习的浩瀚海洋里,循环神经网络(RNN)宛如一颗独特的明珠,专门用于剖析序列数据,如文本、语音、时间序列等。无论是预测股票走势,还是理解自然语言,RNN 都发挥着举足轻重的作用。…...
前端---HTML(一)
HTML_网络的三大基石和html普通文本标签 1.我们要访问网络,需不需要知道,网络上的东西在哪? 为什么我们写,www.baidu.com就能找到百度了呢? 我一拼ping www.baidu.com 就拼到了ip地址: [119.75.218.70]…...
SQL 复杂查询
目录 复杂查询 一、目的和要求 二、实验内容 (1)查询出所有水果产品的类别及详情。 查询出编号为“00000001”的消费者用户的姓名及其所下订单。(分别采用子查询和连接方式实现) 查询出每个订单的消费者姓名及联系方式。 在…...
银河麒麟桌面系统——桌面鼠标变成x,窗口无关闭按钮的解决办法
银河麒麟桌面系统——桌面鼠标变成x,窗口无关闭按钮的解决办法 1、支持环境2、详细操作说明步骤1:用root账户登录电脑步骤2:导航到kylin-wm-chooser目录步骤3:编辑default.conf文件步骤4:重启电脑 3、结语 Ὁ…...
抓包之使用chrome的network面板
写在前面 本文看下工作中非常非常常用的chrome的network面板功能。 官方介绍:地址。 1:前置 1.1:打开 右键-》检查,或者F12。 1.2:组成部分 2:控制器常用功能 详细如下图: 接着我们挑选其…...
避坑ffmpeg直接获取视频fps不准确
最近在做视频相关的任务,调试代码发现一个非常坑的点,就是直接用ffmpeg获取fps是有很大误差的,如下: # GPT4o generated import ffmpegprobe ffmpeg.probe(video_path, v"error", select_streams"v:0", sho…...
大数据新视界 -- 大数据大厂之 Hive 函数库:丰富函数助力数据处理(上)(11/ 30)
💖💖💖亲爱的朋友们,热烈欢迎你们来到 青云交的博客!能与你们在此邂逅,我满心欢喜,深感无比荣幸。在这个瞬息万变的时代,我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…...
深入解析 Django 中数据删除的最佳实践:以动态管理镜像版本为例
文章目录 引言场景与模型设计场景描述 删除操作详解1. 删除单个 Tag2. 批量删除 Tags3. 删除前确认4. 日志记录 高阶优化与问题分析1. 外键约束与误删保护2. 并发删除的冲突处理3. 使用软删除 结合 Django Admin 的实现总结与实践思考 引言 在现代应用开发中,服务和…...
【java】sdkman-java多环境切换工具
#java #env #sdk #lcshand 首先我们来复习一下,可参考我原来的文章: python多个版本的切换可用pyenv nodejs多个版本的切换可用nvm 同样,java多个版本的切换可用sdkman和jenv,我偏重于使用sdkman,因为有时候我也需要…...
11.25c++继承、多态
练习: 编写一个 武器类 class Weapon{int atk; }编写3个武器派生类:短剑,斧头,长剑 class knife{int spd; }class axe{int hp; }class sword{int def; }编写一个英雄类 class Hero{int atk;int def;int spd;int hp; public:所有的…...
STM32F103外部中断配置
一、外部中断 在上一节我们介绍了STM32f103的嵌套向量中断控制器,其中包括中断的使能、失能、中断优先级分组以及中断优先级配置等内容。 1.1 外部中断/事件控制器 在STM32f103支持的60个可屏蔽中断中,有一些比较特殊的中断: 中断编号13 EXTI…...
应用升级/灾备测试时使用guarantee 闪回点迅速回退
1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间, 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点,不需要开启数据库闪回。…...
Qt Widget类解析与代码注释
#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码,写上注释 当然可以!这段代码是 Qt …...
关于nvm与node.js
1 安装nvm 安装过程中手动修改 nvm的安装路径, 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解,但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后,通常在该文件中会出现以下配置&…...
MODBUS TCP转CANopen 技术赋能高效协同作业
在现代工业自动化领域,MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步,这两种通讯协议也正在被逐步融合,形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...
(转)什么是DockerCompose?它有什么作用?
一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器。 Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...
Spring数据访问模块设计
前面我们已经完成了IoC和web模块的设计,聪明的码友立马就知道了,该到数据访问模块了,要不就这俩玩个6啊,查库势在必行,至此,它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据(数据库、No…...
Springboot社区养老保险系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,社区养老保险系统小程序被用户普遍使用,为方…...
iview框架主题色的应用
1.下载 less要使用3.0.0以下的版本 npm install less2.7.3 npm install less-loader4.0.52./src/config/theme.js文件 module.exports {yellow: {theme-color: #FDCE04},blue: {theme-color: #547CE7} }在sass中使用theme配置的颜色主题,无需引入,直接可…...
省略号和可变参数模板
本文主要介绍如何展开可变参数的参数包 1.C语言的va_list展开可变参数 #include <iostream> #include <cstdarg>void printNumbers(int count, ...) {// 声明va_list类型的变量va_list args;// 使用va_start将可变参数写入变量argsva_start(args, count);for (in…...
LabVIEW双光子成像系统技术
双光子成像技术的核心特性 双光子成像通过双低能量光子协同激发机制,展现出显著的技术优势: 深层组织穿透能力:适用于活体组织深度成像 高分辨率观测性能:满足微观结构的精细研究需求 低光毒性特点:减少对样本的损伤…...
