C++设计模式:单例模式(饿汉式、懒汉式)
单例模式是什么?
单例模式是一种创建型的软件设计模式。通过单例模式的设计,使得创建的类在当前进程中只有唯一一个实例,并提供一个全局性的访问点,这样可以规避因频繁创建对象而导致的内存飙升情况。
单例模式有三个要点
- 私有化构造函数:这样外界就无法自由地创建类对象,进而阻止了多个实例的产生。
- 类定义中含有该类的唯一静态私有对象:静态变量存放在全局存储区,且是唯一的,供所有对象使用。
- 用公有的静态函数来获取该实例:提供了访问接口。
基础代码
h文件:
//
// Created by qiaowei on 2023-12-25.
//#ifndef RADARDATACONTROLLER_MAIN_WINDOW_HANDLER_H
#define RADARDATACONTROLLER_MAIN_WINDOW_HANDLER_H#include <QObject>namespace handler {class MainWindowHandler : public QObject{public:virtual ~MainWindowHandler() override;static MainWindowHandler* instance();private:explicit MainWindowHandler(QObject* parent = nullptr);private:/*** @date 2023-12-25 19:32* @author qiao wei* @brief MainwindowHandler实例指针。static函数只能访问静态成员变量或函数,所以必须为static*/static MainWindowHandler* instance_;};} // handler#endif //RADARDATACONTROLLER_MAIN_WINDOW_HANDLER_H
cpp文件:
//
// Created by qiaowei on 2023-12-25.
//#include "main_window_handler.h"namespace handler {// 静态非const整型成员变量必须在类外定义。MainWindowHandler* MainWindowHandler::instance_ = nullptr;MainWindowHandler::MainWindowHandler(QObject* parent) : QObject(parent) {}MainWindowHandler::~MainWindowHandler() {}MainWindowHandler* MainWindowHandler::instance() {if (nullptr == instance_) {instance_ = new MainWindowHandler{nullptr};}return instance_;}} // handler
单例模式一般分为懒汉式和饿汉式。
单例模式的基础代码不符合线程安全,因此引出了懒汉式和饿汉式单例模式。懒汉式:指全局的单例实例在第一次被使用时构建。饿汉式:全局的单例实例在类装载(ClassLoader)时构建(饿汉式单例性能优于懒汉式单例)。
懒汉式和饿汉式的区别:
- 懒汉式默认不会实例化,外部什么时候调用什么时候new。饿汉式在类加载的时候就实例化,并且创建单例对象。
- 懒汉式是延时加载,在需要的时候才创建对象,而饿汉式是在虚拟机启动的时候就会创建。
- 懒汉式在多线程中是线程不安全的,而饿汉式是不存在多线程安全问题的。
懒汉单例模式(需要时再实例化单例对象)
懒汉模式中使用QMutex,QMutexLocker进行同步锁。
h文件:
//
// Created by qiaowei on 2023-12-25.
//#ifndef RADARDATACONTROLLER_MAIN_WINDOW_HANDLER_H
#define RADARDATACONTROLLER_MAIN_WINDOW_HANDLER_H#include <QObject>namespace handler {class MainWindowHandler : public QObject{public:/*** @date 2023-12-25 21:54* @author qiao wei* @version 1.0* @brief 拷贝构造函数。删除拷贝构造,防止对象通过拷贝构造创建对象。* @param* @return* @throws*/MainWindowHandler(const MainWindowHandler& value) = delete;virtual ~MainWindowHandler() override;/*** @date 2023-12-25 21:56* @author qiao wei* @version 1.0* @brief 赋值操作符。删除赋值操作符,防止简单类型通过赋值创建对象。* @param* @return* @throws*/MainWindowHandler& operator=(const MainWindowHandler& value) = delete;/*** @date 2023-12-25 21:47* @author qiao wei* @version 1.0* @brief 返回MainWindowHandler*指针的static函数。* @param* @return Mainwindow*指针。* @throws*/static MainWindowHandler* instance();private:explicit MainWindowHandler(QObject* parent = nullptr);private:/*** @date 2023-12-25 19:32* @author qiao wei* @brief MainwindowHandler实例指针。*/static MainWindowHandler* instance_;static QMutex mutex_;};} // handler#endif //RADARDATACONTROLLER_MAIN_WINDOW_HANDLER_H
cpp文件:
//
// Created by qiaowei on 2023-12-25.
//#include <QMutexLocker>
#include <QMutex>
#include "main_window_handler.h"namespace handler {// 静态成员在类外初始化。MainWindowHandler* MainWindowHandler::instance_ = nullptr;QMutex MainWindowHandler::mutex_;MainWindowHandler::~MainWindowHandler() {delete instance_;instance_ = nullptr;}MainWindowHandler* MainWindowHandler::instance() {// 第1次检查:实例化单例对象后,就不会再进入加锁逻辑。if (nullptr == instance_) {// 加同步锁。QMutexLocker mutex_locker(&mutex_);// 第2次检查:可能2个线程同时通过第1次检查,1个线程获得锁时,可能另外1个线程已经实例化单体。if (nullptr == instance_) {instance_ = new MainWindowHandler{nullptr};}}return instance_;}MainWindowHandler::MainWindowHandler(QObject* parent) : QObject(parent) {}} // handler
饿汉单例模式(一开始就初始化单例对象)
饿汉模式一
饿汉模式一缺点:不会调用析构函数,需要手动delete。
h文件
//
// Created by qiaowei on 2023-12-25.
//#ifndef RADARDATACONTROLLER_EAGER_SINGLETON_H
#define RADARDATACONTROLLER_EAGER_SINGLETON_H#include <QObject>namespace handler {class EagerSingleton : public QObject{public:virtual ~EagerSingleton() override;static EagerSingleton* instance();private:explicit EagerSingleton(QObject* parent = nullptr);private:static EagerSingleton* instance_;};} // handler#endif //RADARDATACONTROLLER_EAGER_SINGLETON_H
cpp文件
//
// Created by qiaowei on 2023-12-25.
//#ifndef RADARDATACONTROLLER_EAGER_SINGLETON_H
#define RADARDATACONTROLLER_EAGER_SINGLETON_H#include <QObject>namespace handler {class EagerSingleton : public QObject{public:virtual ~EagerSingleton() override;static EagerSingleton* instance();private:explicit EagerSingleton(QObject* parent = nullptr);private:static EagerSingleton* instance_;};} // handler#endif //RADARDATACONTROLLER_EAGER_SINGLETON_H
饿汉模式二
h文件
//
// Created by qiaowei on 2023-12-25.
//#ifndef RADARDATACONTROLLER_EAGER_SINGLETON_2_H
#define RADARDATACONTROLLER_EAGER_SINGLETON_2_H#include <QObject>namespace handler {class EagerSingleton2 : public QObject{public:static EagerSingleton2* instance();virtual ~EagerSingleton2();private:explicit EagerSingleton2(QObject* parent = nullptr);private:static EagerSingleton2 eager_singleton_;};} // handler#endif //RADARDATACONTROLLER_EAGER_SINGLETON_2_H
cpp文件
//
// Created by qiaowei on 2023-12-25.
//#include "eager_singleton_2.h"namespace handler {EagerSingleton2 EagerSingleton2::eager_singleton_;EagerSingleton2* EagerSingleton2::instance() {return &eager_singleton_;}EagerSingleton2::~EagerSingleton2() {}EagerSingleton2::EagerSingleton2(QObject *parent) : QObject(parent) {}} // handler
饿汉模式总结:
由于在定义静态变量的时候实例化单例类,因此在类加载的时候就已经创建了单例对象,可确保单例对象的唯一性。
饿汉模式缺点:
无论系统运行时是否需要使用该单例对象,都会在类加载时创建对象,资源利用效率不高。
相关文章:
C++设计模式:单例模式(饿汉式、懒汉式)
单例模式是什么? 单例模式是一种创建型的软件设计模式。通过单例模式的设计,使得创建的类在当前进程中只有唯一一个实例,并提供一个全局性的访问点,这样可以规避因频繁创建对象而导致的内存飙升情况。 单例模式有三个要点 私有化…...
Django 访问前端页面一直在转异常:ReferenceError:axios is not defined
访问:http://127.0.0.1:8080/ my.html 一、异常: 二、原因 提示:axios找不到!! 查看代码<script src"https://unpkg.com/axios/dist/axios.min.js"></script>无法访问到官网 三、解决 Using j…...
C语言中关于指针的理解
#include <stdio.h> int main() {int a11;int *p&a; //因为a是整型的,所以我们定义指针p的时候要和a的类型一样char b;char *pa&b; //同理,b是字符型,所以这里的pa也要用字符型return 0; }因为*p指向的是地址&…...
MySQL MVCC精讲
版本链 我们前面说过,对于使用InnoDB存储引擎的表来说,它的聚簇索引记录中都包含两个必要的隐藏列(row_id并不是必要的,我们创建的表中有主键或者非NULL的UNIQUE键时都不会包含row_id列): trx_idÿ…...
如何快速删除pdf周围的空白
问题:写论文往往需要pdf格式的图片,但pdf往往四周存在大量空白需要手动截图很麻烦 解决: 打开命令行输入:pdfcrop 图片名.pdf...
蓝桥杯c/c++程序设计——数位排序
数位排序【第十三届】【省赛】【C组】 题目描述 小蓝对一个数的数位之和很感兴趣,今天他要按照数位之和给数排序。 当两个数各个数位之和不同时,将数位和较小的排在前面,当数位之和相等时,将数值小的排在前面。 例如࿰…...
【通讯录案例-搭建登录界面 Objective-C语言】
一、来看我们这个通讯录案例 1.接下来啊,我们来做这个通讯录案例, 然后呢,做这么一个应用程序啊, 我们第一步呢,先把界面儿搭了, 然后呢,搭之前,简单的来分析一下, 首先呢,这是,中间儿的这一块儿, 1)有个“账户”、“密码”,这一块儿, 这是一个什么控制器,…...
二叉搜索树、AVL、红黑树、B树
文章目录 二叉搜索树2. avl树3. 红黑树 b树和b树比较适合与磁盘打交道的,磁盘操作耗时,这些树 矮,红黑树、avL树高,比较适合与内存打交道。 二叉搜索树 找一个节点的前驱和后继: 前驱:如果节点有左子树&a…...
格密码:傅里叶矩阵
目录 一. 铺垫性介绍 1.1 傅里叶级数 1.2 傅里叶矩阵的来源 二. 格基与傅里叶矩阵 2.1 傅里叶矩阵详细解释 2.2 格基与傅里叶矩阵 写在前面:有关傅里叶变换的解释太多了,这篇博客主要总结傅里叶矩阵在格密码中的运用。对于有一定傅里叶变换基础的同…...
flex--伸缩性
1.flex-basis flex-basis 设置的是主轴方向的基准长度,会让宽度或高度失效。 备注:主轴横向:宽度失效;主轴纵向:高度失效 作用:浏览器根据这个属性设置的值,计算主轴上是否有多余空间&#x…...
linux中主从复制的架构和读写分离的方式
读写分离 互相主从架构注意点 双主双从架构注意点 一主多从架构注意点 读写分离概念部署jdk环境上传文件,解压文件配置环境变量 部署mycat环境mycat配置文件给所有数据库创建访问用户配置 server.xml配置 schema.xml启动mycat查看启动端口日志负载均衡测试 遇到的问…...
Ubuntu 22.04.3 Server 设置静态IP 通过修改yaml配置文件方法
目录 1.查看网卡信息 2.修改yaml配置文件 3.应用新的网络配置 4.重新启动网络服务 文章内容 本文介绍Ubuntu 22.04.3 Server系统通过修改yaml配置文件配置静态 ip 的方法。 1.查看网卡信息 使用ifconfig命令查看网卡信息获取网卡名称 如果出现Command ifconfig not fo…...
EasyCVR无人机推流+人数统计AI算法,助力公共场所人群密度管控
一、背景与需求 在公共场所和大型活动的管理中,人数统计和人群密度控制是非常重要的安全问题。传统的方法可能存在效率低下或准确度不足的情况,无法满足现代社会的需求。TSINGSEE青犀可以利用无人机推流AI人流量统计算法,基于计算机视觉技术…...
Kotlin 接口
Kotlin 的接口可以既包含抽象方法的声明也包含实现;接口无法保存状态;可以有属性但必须声明为抽象或提供访问器实现 1、定义 使用关键字 interface 来定义接口 interface MyInterface {fun bar()fun foo() {// 可选的方法体} } 2、 实现接口 一个类…...
Qt前端技术:5.QSS
这个是表示QFrame中的pushButton中的子类和它子类的子类都将背景变为red 写成大于的时候表示只有直接的子类对象才会变 这个图中的QGroupBox和QPushButton都是QFrame的直接的子类 这个中的QGroupBox是QFrame的直接的子类但是QPushButton 是QGroupBox的子类,QPushB…...
在Centos7中利用Shell脚本:实现MySQL的数据备份
目录 自动化备份MySQL 一.备份数据库脚本 1.创建备份目录 2.创建脚本文件 3.新建配置文件(连接数据库的配置文件) 4.给文件权限(mysql_backup.sh) 编辑 5.执行命令 (mysql_backup.sh) 编辑 二.数据库通过备份恢复 1.创建脚…...
大一C语言查缺补漏 12.24
遗留问题: 6-1 1 在C语言中,如果要保留小数的话,一定要除以2.0,而不是2。 设整型变量m,n,a,b的值均为1,执行表达式(m a>b)||(n a<b)后,表达式的值以及变量m和n的值是&#…...
程序员宝典:常用的免费好物API
六位图片验证码生成:包括纯数字、小写字母、大写字母、大小写混合、数字小写、数字大写、数字大小写等情况。 四位图片验证码生成:四位图片验证码生成,包括纯数字、小写字母、大写字母、大小写混合、数字小写、数字大写、数字大小写等情况。…...
关于“Python”的核心知识点整理大全41
目录 scoreboard.py game_functions.py game_functions.py 14.3.8 显示等级 game_stats.py scoreboard.py scoreboard.py scoreboard.py game_functions.py game_functions.py alien_invasion.py 14.3.9 显示余下的飞船数 ship.py scoreboard.py 我们将最高得分圆整…...
java进阶(二)-java小干货
java一些精干知识点分享 2. java小干货2.1循环遍历2.2可变参数2.3 list和数组转化2.3.1 数组转list2.3.2 list转数组 2.4 值传递和地址传递2.4.1值传递2.4.2 地址传递2.4.3易错点总结 2.5 数据类型2.5.1基础知识2.5.2 基础数据和包装类 2.6 字符串2.6.1 char/String区别2.6.2 .…...
抖音增长新引擎:品融电商,一站式全案代运营领跑者
抖音增长新引擎:品融电商,一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中,品牌如何破浪前行?自建团队成本高、效果难控;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...
什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南
文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果 三、匿名函数与闭包1. 匿名函数(Lambda函…...
push [特殊字符] present
push 🆚 present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中,push 和 present 是两种不同的视图控制器切换方式,它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...
【Linux】Linux 系统默认的目录及作用说明
博主介绍:✌全网粉丝23W,CSDN博客专家、Java领域优质创作者,掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围:SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…...
scikit-learn机器学习
# 同时添加如下代码, 这样每次环境(kernel)启动的时候只要运行下方代码即可: # Also add the following code, # so that every time the environment (kernel) starts, # just run the following code: import sys sys.path.append(/home/aistudio/external-libraries)机…...
Git常用命令完全指南:从入门到精通
Git常用命令完全指南:从入门到精通 一、基础配置命令 1. 用户信息配置 # 设置全局用户名 git config --global user.name "你的名字"# 设置全局邮箱 git config --global user.email "你的邮箱example.com"# 查看所有配置 git config --list…...
【从零开始学习JVM | 第四篇】类加载器和双亲委派机制(高频面试题)
前言: 双亲委派机制对于面试这块来说非常重要,在实际开发中也是经常遇见需要打破双亲委派的需求,今天我们一起来探索一下什么是双亲委派机制,在此之前我们先介绍一下类的加载器。 目录 编辑 前言: 类加载器 1. …...
DiscuzX3.5发帖json api
参考文章:PHP实现独立Discuz站外发帖(直连操作数据库)_discuz 发帖api-CSDN博客 简单改造了一下,适配我自己的需求 有一个站点存在多个采集站,我想通过主站拿标题,采集站拿内容 使用到的sql如下 CREATE TABLE pre_forum_post_…...
第一篇:Liunx环境下搭建PaddlePaddle 3.0基础环境(Liunx Centos8.5安装Python3.10+pip3.10)
第一篇:Liunx环境下搭建PaddlePaddle 3.0基础环境(Liunx Centos8.5安装Python3.10pip3.10) 一:前言二:安装编译依赖二:安装Python3.10三:安装PIP3.10四:安装Paddlepaddle基础框架4.1…...
