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…...

IDEA运行Tomcat出现乱码问题解决汇总
最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…...

springboot 百货中心供应链管理系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,百货中心供应链管理系统被用户普遍使用,为方…...

React第五十七节 Router中RouterProvider使用详解及注意事项
前言 在 React Router v6.4 中,RouterProvider 是一个核心组件,用于提供基于数据路由(data routers)的新型路由方案。 它替代了传统的 <BrowserRouter>,支持更强大的数据加载和操作功能(如 loader 和…...
FastAPI 教程:从入门到实践
FastAPI 是一个现代、快速(高性能)的 Web 框架,用于构建 API,支持 Python 3.6。它基于标准 Python 类型提示,易于学习且功能强大。以下是一个完整的 FastAPI 入门教程,涵盖从环境搭建到创建并运行一个简单的…...

微信小程序云开发平台MySQL的连接方式
注:微信小程序云开发平台指的是腾讯云开发 先给结论:微信小程序云开发平台的MySQL,无法通过获取数据库连接信息的方式进行连接,连接只能通过云开发的SDK连接,具体要参考官方文档: 为什么? 因为…...

IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)
文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...
rnn判断string中第一次出现a的下标
# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问(基础概念问题) 1. 请解释Spring框架的核心容器是什么?它在Spring中起到什么作用? Spring框架的核心容器是IoC容器&#…...

【笔记】WSL 中 Rust 安装与测试完整记录
#工作记录 WSL 中 Rust 安装与测试完整记录 1. 运行环境 系统:Ubuntu 24.04 LTS (WSL2)架构:x86_64 (GNU/Linux)Rust 版本:rustc 1.87.0 (2025-05-09)Cargo 版本:cargo 1.87.0 (2025-05-06) 2. 安装 Rust 2.1 使用 Rust 官方安…...
【JavaSE】多线程基础学习笔记
多线程基础 -线程相关概念 程序(Program) 是为完成特定任务、用某种语言编写的一组指令的集合简单的说:就是我们写的代码 进程 进程是指运行中的程序,比如我们使用QQ,就启动了一个进程,操作系统就会为该进程分配内存…...