QT 使用单例模式

目录

1. 单例模式介绍

2.单例模式实现


 

1. 单例模式介绍

   有些时候我们在做 qt 项目的时候,要用到很多类. 例如我们用到的类有 A,B,C,D. 其中,A 是 B,C,D 中都需要用到的类,A 类非常的抢手. 但是,A 类非常的占内存,定义一个 A 对象需要 500M 内存,假如在 B,C,D 中都定义一个 A 类对象,对 内存的消耗是可想而知的.

所以 B,C,D 分别都定义一个 A 类对象是不可能的. 那么我们此时就希望: 能不能把 A 定义成"全局变量",然后这样子 B,C,D 类都能访问,并且整个程序就只有这一个 A?

答案是可以的,定义 A 的时候以单例模式定义即可

单例模式作为一种常用的软件设计模式,主要是用来保证系统中只有一个实例,例如一般一个程序中只有一 个日志输出实例,一个系统中只有一个数据库连接实例,这时候用单例模式非常合适。

单例模式用来做什么

正如之前所说,单例模式:

(1) 整个程序只有一个对象;

(2) 整个程序都能访问到它;

(3) 分为"懒汉模式"和"饿汉模式";

(4) "懒汉模式"是用到单例的时候才创建,否则不创建对象;

(5) "饿汉模式"是在程序启动时就需要创建变量;

懒汉模式是时间换空间,饿汉模式是空间换时间。

单例模式是在大型项目用到非常多的,例如:

(1) 一个日记记录类,必须整个程序只能有一个,假如有 2 个,在写日志文件时会相互"践踏".

(2) 数据库操作,连接类,必须整个程序只能有一个,假如有 2 个就会出问题,你想看假如 2 个进程同时使用 同一个账号,然后写入同一个数据会发生什么事情...

单例模式有效的解决了重复定义对象的问题,假如配合互斥锁,还可以解决多进程,线程之间的同步互斥问题, 也就是同一时间只能有一个进程操作单例对象。

2.单例模式实现

设计单例模式非常简单:

cpp文件实例:

//这句一定要写,因为 self 是静态变量,必须要初始化值
ClassA* ClassA::self = NULL;
ClassA *ClassA::getInstance()
{
 //判断是否是第一次调用
 //假如不为 NULL,会直接 return
 if (self == NULL) {
 //防止多进程同时调用创建 2 个对象的问题
 //原理是因为是静态变量只会定义一次
 static QMutex mutex;
 //上锁
 QMutexLocker locker(&mutex);
 //在判断一次,防止其它进程抢先 new 过了
 if (self == NULL) {
 self = new ClassA;
 }
 }
 return self; //返回指针
}

h头文件实例:

class ClassA : public QObject
{
 Q_OBJECT
public:
 //通过它获取 self 指针,这个函数是静态调用,不需要创建对象就可以访问
 static ClassA *getInstance(); //返回自身的指针
 //构造函数
 explicit ClassA(QObject *parent = 0);
 void hello(){ //一个普通函数
 qDebug() << "hello world";
 }
private:
 static ClassA *self; //静态指针
};
#endif // ICONFONT_H

在其他类里的调用方法:

ClassA::getInstance()->hello();

 其中:

     ClassA::getInstance()会获取全局的 self 指针,通过这个指针我们可以访问到里边的函数。在任何类里,都可以 无条件访问 A 对象,并且不需要创建 A 对象,而且 A 对象全局只有一个实例:

(1) 在类 A 里定义一个静态的指针 self;

(2) 当调用获取 A 对象的指针时,判断这个 self 是否为空,假如为空则创建新对象并赋值给 self 并返回 self,存 在则直接返回 self;

在此使用用的最多的"懒汉模式"进行演示:

cpp 代码如下(以数据库为例(多个 ui 界面都使用到此类)):

#include "qmqttclient.h"
#include <QMutex>
#include <QMutexLocker>
#include <QMessageBox>
//构造函数
QmqttClient::QmqttClient()
{
 
}
//这句一定要写,因为 self 是静态变量,必须要初始化值
QmqttClient* QmqttClient::mqttSelf = NULL;
QmqttClient *QmqttClient::getInstance()
{
 //判断是否是第一次调用
 //假如不为 NULL,会直接 return
 if (mqttSelf == NULL) {
 //防止多进程同时调用创建 2 个对象的问题
 //原理是因为是静态变量只会定义一次
 static QMutex mutex;
 //上锁 QMutexLocker 会锁住 mutex,当 QMutexLocker 被释放的时候自动解锁
 //locker 是局部变量,所以 getInstance 函数结束时会自动解锁
 QMutexLocker locker(&mutex);
 //在判断一次,防止其它进程抢先 new 过了
 if (mqttSelf == NULL) {
 mqttSelf = new QmqttClient;
 }
 }
 return mqttSelf; //返回指针
}

头文件

#ifndef QMQTTCLIENT_H
#define QMQTTCLIENT_H
#include <QObject>
#include "qmqtt.h"
#include <QtCore>
class QmqttClient : public QObject{
 Q_OBJECT
public:
 //通过它获取 self 指针,这个函数是静态调用,不需要创建对像就可以访问,函数名
自定义
 //这个函数的作用是给别人获取它的静态对象 返回自身的指针
 static QmqttClient *getInstance();
// void hello(){ //一个普通函数
// qDebug() << "hello world";
private:
 QmqttClient(); //构造函数,写在 private 下,不允许 new 生成单例
 static QmqttClient *mqttSelf;//静态指针
};

在其他类里的调用方法:

QmqttClient::getInstance()->mqttClient->setHost(ui->lEditServerIP->text()); //服务 器 IP QmqttClient::getInstance()->mqttClient->setPort(1883);//端口号

 其中: QmqttClient::getInstance()会获取全局的 self 指针,通过这个指针我们可以访问到里边的函数. 在任何类里,都可以无条件访问 A 对象,并且不需要创建 A 对象,而且 A 对象全局只有一个实例: 注意:可以把多个对象放到单例模式

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/64523.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

爬虫获取电影数据----以沈腾参演电影为例

数据可视化&分析实战 1.1 沈腾参演电影数据获取 文章目录 数据可视化&分析实战前言1. 网页分析2. 构建数据获取函数2.1 网页数据获取函数2.2 网页照片获取函数 3. 获取参演影视作品基本数据4. 电影详细数据获取4.1 导演、演员、描述、类型、投票人数、评分信息、电影海…

e6zzseo:外贸独立站怎么推广

外贸独立站的推广需要一系列综合性的策略和方法&#xff0c;以吸引目标市场的访问者&#xff0c;并将他们转化为潜在客户。以下是一些推广外贸独立站的建议&#xff1a; 1. 搜索引擎优化&#xff08;SEO&#xff09;&#xff1a; e6zzseo认为优化网站可以适应搜索引擎的要求&a…

elementUi select下拉框触底加载异步分页数据

在Element UI中&#xff0c;可以通过监听select下拉框的visible-change事件来实现触底加载下一页的效果。 方式一&#xff1a;利用elementUi的事件 具体步骤如下&#xff1a; 首先&#xff0c;在select组件中设置&#xff1a;visible-change"handleVisibleChange"…

MySQL数据库基础

目标&#xff1a; 1.数据库操作&#xff1a;创建数据库&#xff0c;删除数据库 2.常用数据类型 3.表的操作&#xff1a;创建表&#xff0c;删除表 数据库操作 &#xff08;1&#xff09;显示数据库 show databases&#xff1b; &#xff08;2&#xff09;创建数据库 创建一个…

sentinel简单使用

核心demo&#xff1a; 1 引入依赖: <dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-core</artifactId><version>1.8.0</version> </dependency>2 核心代码&#xff1a; 3 限流保护代码&#xff1a;…

Pandaer的iPhone手机壳

哇塞&#xff0c;Pandaer的设计太棒了&#xff01;手机壳的花样多到让我眼花缭乱&#xff0c;好多系列设计都很有意思&#xff0c;让人有集齐的冲动。我最近入手了几个iPhone的手机壳&#xff0c;它有亮色和透明的款式&#xff0c;亮色的壳内部也是亮的&#xff0c;因为手机壳全…

HTTP隧道识别与防御:机器学习的解决方案

随着互联网的快速发展&#xff0c;HTTP代理爬虫已成为数据采集的重要工具。然而&#xff0c;随之而来的是恶意爬虫对网络安全和数据隐私的威胁。为了更好地保护网络环境和用户数据&#xff0c;我们进行了基于机器学习的HTTP代理爬虫识别与防御的研究。以增强对HTTP代理爬虫的识…

CentOS下ZLMediaKit的可视化管理网站MediaServerUI使用

一、简介 按照 ZLMediaKit快速开始 编译运行ZLMediaKit成功后&#xff0c;我们可以运行其合作开源项目MediaServerUI&#xff0c;来对ZLMediaKit进行可视化管理。通过MediaServerUI&#xff0c;我们可以实现在浏览器查看ZLMediaKit的延迟率、负载率、正在进行的推拉流、服务器…

抄袭可耻 - MISAYAONE抄袭对比图(Python)

序号原创博客(伏城之外)抄袭博客(MISAYAONE)对比图1华为OD机试 - 数组组成的最小数字(Java & JS & Python)_华为od 数组组成的最小数字_伏城之外的博客-CSDN博客2023华为OD机试真题 Python 实现【最小数字】_普通网友的博客-CSDN博客2

【C++】做一个飞机空战小游戏(六)——给两架飞机设置不同颜色(cout输出彩色字符、结构体使用技巧)

[导读]本系列博文内容链接如下&#xff1a; 【C】做一个飞机空战小游戏(一)——使用getch()函数获得键盘码值 【C】做一个飞机空战小游戏(二)——利用getch()函数实现键盘控制单个字符移动【C】做一个飞机空战小游戏(三)——getch()函数控制任意造型飞机图标移动 【C】做一个飞…

手写springboot

前言 首先确定springboot在spring基础上主要做了哪些改动&#xff1a;内嵌tomcatspi技术动态加载 一、基本实现 1. 建一个工程目录结构如下&#xff1a; springboot: 源码实现逻辑 user : 业务系统2.springboot工程项目构建 1. pom依赖如下 <dependencies>…

无涯教程-Perl - endnetent函数

描述 此功能告诉系统您不再希望使用getnetent从网络列表中读取条目。 语法 以下是此函数的简单语法- endnetent返回值 此函数不返回任何值。 例 以下是显示其基本用法的示例代码- #!/usr/bin/perluse Socket;while ( ($name, $aliases, $addrtype, $net) getnetent() )…

Spring Web

◆ Spring整合web环境 - Javaweb三大组件及环境特点 - Spring整合web环境的思路及实现 把ApplicationContext放在ServleContent域【listen组件中】中 ContextLoaderListener &#xff1a;部分代码写死了 /*** 配置通用的Spring容器的创建&#xff0c;只需要创建一次就可以*/…

halcon 学习笔记

图像的参数 图形参数 Iconic, 包括 image, region, XLD 1.1 image 图像由一个或者多个通道组成&#xff0c;是大小相同的矩阵&#xff0c;包含各种像素类型的灰度值 在图像显示界面&#xff0c;按ctrl健&#xff0c;可以查看当前的像素值 灰度图 一个通道像素点存放在一个矩…

最新AI创作系统ChatGPT源码V2.5.8/支持GPT4.0+GPT联网提问/支持ai绘画Midjourney+Prompt+MJ以图生图+思维导图生成!

使用Nestjs和Vue3框架技术&#xff0c;持续集成AI能力到系统&#xff01; 最新版【V2.5.8】更新&#xff1a; 新增 MJ 官方图片重新生成指令功能同步官方 Vary 指令 单张图片对比加强 Vary(Strong) | Vary(Subtle)同步官方 Zoom 指令 单张图片无限缩放 Zoom out 2x | Zoom ou…

网络安全进阶学习第十四课——MSSQL注入

文章目录 一、MSsql数据库二、MSsql结构三、MSsql重点表1、master 数据库中的Sysdatabases 表2、Sysobjects 表3、Syscolumns 表 四、Mssql常用函数五、Mssql的报错注入六、Mssql的盲注常用以下函数进行盲注&#xff1a; 七、联合注入1、获取当前表的列数2、获取当前数据库名3、…

flask-----蓝图

1.引入蓝图 flask都写在一个文件中&#xff0c;项目这样肯定不行&#xff0c;会导致循环导入的问题&#xff0c;分目录&#xff0c;分包&#xff0c;使用蓝图划分目录。 2.使用蓝图 步骤如下&#xff1a; -1 实例化得到一个蓝图对象-order_blueBlueprint(order,__name__,tem…

Java thymeleaf bug排查记录

刚学Java 做项目时报了一个错误 一时间看的莫名其妙 EL1008E: Property or field createTime cannot be found on object of type java.util.HashMap - maybe not public or not valid? 随即向上排查至第一个报错&#xff0c;发现是thymeleaf渲染时报错。 Exception proces…

Spring Boot Admin 环境搭建与基本使用

Spring Boot Admin 环境搭建与基本使用 一、Spring Boot Admin是什么二、提供了那些功能三、 使用Spring Boot Admin3.1搭建Spring Boot Admin服务pom文件yml配置文件启动类启动admin服务效果 3.2 common-apipom文件feignhystrix 3.3服务消费者pom文件yml配置文件启动类control…

dotConnect for DB2 Crack

dotConnect for DB2 Crack dotConnect for DB2是一个增强的DB2 ORM数据提供程序&#xff0c;它构建在ADO.NET技术和IBM DB2.NET数据提供程序之上&#xff0c;为开发基于DB2的数据库应用程序提供了一个完整的解决方案。它允许您轻松地将DB2数据与广泛使用的面向数据的技术集成&a…