Qt中的单例模式:实现一个单例的界面类

2023-11-06


前言

本文主要讲述了使用加锁的懒汉式来实现单例,文中示例将一个界面类修改为单例类,并在主界面获取多次该类的实例来进行测试,看到结果表明也只生成了唯一的实例,这个简单的示例是自己对单例模式的一个学习认识的总结。文中讲述如有错误之处,欢迎大家批评指正。


提示:以下是本篇文章正文内容,下面案例可供参考

一、什么是单例模式

单例模式,属于创建类型的一种常用的软件设计模式。通过单例模式的方法创建的类保证这个类仅有一个实例,并提供一个访问它的全局访问点。

二、单例模式的优缺点及使用场景

可以看这篇文章,总结的挺全面:单例模式优缺点及应用场景

三、Qt中单例类的创建

1.config.h

#ifndef CONFIG_H
#define CONFIG_H

#include <QWidget>
#include <QMutex>
#include <QMutexLocker>
#include <QDebug>

namespace Ui {
class Config;
}

class Config : public QWidget
{
    Q_OBJECT

public:
    //explicit Config(QWidget *parent = nullptr);
    ~Config();

    //提供一个公有的静态接口,获取该类的实例
    static Config* getInstance();

private:
    Ui::Config *ui;

    //构造函数私有化,防止外界通过构造创建该类的实例
    explicit Config(QWidget *parent = nullptr);

    //添加私有静态指针变量指向该类的唯一实例
    static Config* instance;
};

#endif // CONFIG_H

2.config.cpp

#include "config.h"
#include "ui_config.h"

//类外初始化
Config* Config::instance = nullptr;
QMutex mutex;

Config::Config(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Config)
{
    ui->setupUi(this);
    this->setAttribute(Qt::WA_QuitOnClose,false);   //设置随主窗口关闭而关闭

}

Config::~Config()
{
    qDebug()<<"~ Config";
    delete ui;
}

//加锁的懒汉式实现
Config* Config::getInstance()
{
    //当多线程获取单例时有可能引发竞态条件
    static QMutex mutex;
    if(!instance)
    {
        QMutexLocker locker(&mutex);   //加锁,解决线程安全的问题
        if(!instance)
        {
            qDebug()<<"new Config";
            instance = new Config;   //注意内存泄露问题
        }
    }
    return instance;
}

四、单例类的使用/测试

1.widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include "config.h"   //包含单例类头文件即可通过接口获取实例

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

private slots:
    void on_pb_config_clicked();
    void on_pb_config_1_clicked();
    void on_pb_config_2_clicked();

private:
    Ui::Widget *ui;

    //Config* instance = nullptr;
};
#endif // WIDGET_H

2.widget.cpp

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    //可以在主界面构造时来获取单例类的实例,配合析构
    //instance = Config::getInstance();
}

Widget::~Widget()
{
    //析构中将单例类实例进行delete,防止内存泄露
    //if(instance)
    //{
    //    delete instance;
    //}
    delete ui;
}

void Widget::on_pb_config_clicked()
{
    //显示构造时创建的实例界面
    //instance->show();
}

//获取了两次类的实例,却只有一次类的构造函数被调用,表明只生成了唯一实例
void Widget::on_pb_config_1_clicked()
{
    Config* instance_1 = Config::getInstance();
    instance_1->show();
}

void Widget::on_pb_config_2_clicked()
{
    Config* instance_2 = Config::getInstance();
    instance_2->show();
}

3.输出结果
界面上两个按钮分别点击,只会出现一个界面,查看打印输出处也只出现了一次"new Config",任意一个按钮点击出现界面后,另一个按钮点击无效果。


总结

其实目前的我对设计模式这方面还是不太了解的,所以还是需要加强学习的。软件的设计模式有很多,没必要为了设计模式而去写设计模式,主要看那些设计模式解决的问题是不是就是你遇到的问题呢?结合项目实际,选择你需要的。

本文讲述的单例设计模式,正如参考文章中所说:

You need to have one and only one object of a type in system
你需要系统中只有唯一一个实例存在的类的全局变量的时候才使用单例。

如果使用单例,应该用什么样子的?
越小越好,越简单越好,线程安全,内存不泄露。

hello:
共同学习,共同进步,如果还有相关问题,可在评论区留言进行讨论。

参考文章:
C++ 单例模式总结与剖析
c++ 设计模式(一) 单例模式

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Qt中的单例模式:实现一个单例的界面类 的相关文章

  • Android 版 Qt 和 BoringSSL

    我正在开发一个基于 Qt 的 Android 应用程序 它使用 QSslSocket 下载数据 由于 Android 从 OpenSSL 转向 BoringSSL 因为依赖 OpenSSL 库的 Marshmallow Qt 程序在 And
  • cmake 找不到 Qt4

    由于4 8 0已经发布 我重新安装了Qt 现在我也想使用cmake 为了使 cmake 工作 我记得必须添加 mingw bin 文件夹 QtSDK Desktop Qt 4 7 3 到Qt4 7 3中的PATH 所以我猜测在中会有一个类似
  • 如何在Qt3D中优化点云渲染

    我正在尝试使用 Qt3D 显示大型点云 20M pts 我第一次发现这个图书馆https github com MASKOR Qt3DPointcloudRenderer https github com MASKOR Qt3DPointc
  • 在 Windows 上以 QML 播放 RTSP 视频

    我正在尝试将 QML 中的 RTSP 流播放到视频标签中 如下所示 Repeater model 8 Video Layout fillWidth true Layout fillHeight true fillMode VideoOutp
  • 在信号/槽处理期间删除 QObject

    我知道从槽处理中删除 QObject 可能会使应用程序崩溃 因为它可能有其他排队的事件 因此 我将使用 obj gt deleteLater 而不是使用 delete obj 据我所知 obj 等待处理所有排队的事件 然后 删除 obj Q
  • 如何从键盘为 QTableWidget 创建信号?

    我有一张桌子 可以通过左 右 上 下按钮在里面移动 现在 当我停留在某个单元格并按空格键时 我需要创建一个信号 该信号还应该带来该单元格的坐标 我尝试使用 QTableWidget 的标准信号 但它不起作用 我该如何解决这个问题 创建一个单
  • PySide6.1 与 matplotlib 3.4 不兼容

    当我只安装PySide6时 GUI程序运行良好 但是一旦我安装了matplotlib及其依赖包 包括pyqt5 则GUI程序将无法运行并输出以下错误消息 This application failed to start because no
  • 如何在Qt中更快地读取数据?

    Qt读取数据库比C 慢吗 我想我错过了一些东西 为了比较阅读速度 我在 Qt 中编写了以下内容 QElapsedTimer t t start int count 0 QString cs Driver SQL Server Server
  • 使用 QTestLib 时抑制 qDebug

    我正在向 Qt 中的项目添加单元测试 并希望使用 QTestLib 我已经设置了测试并且它们运行良好 问题是在项目中我们重写了 qDebug 以输出到我们自己的日志文件 这在运行应用程序时效果很好 问题是当我测试类时 它有时会开始记录 然后
  • QWebView等待加载

    bool MainWindow waitForLoad QWebView view QEventLoop loopLoad QTimer timer QObject connect view SIGNAL loadFinished bool
  • 使用样式表时的 QTabWidget tabPosition

    我目前正在使用样式表来设计应用程序的主题 这是我用于 QTabWidget 的样式表 QTabBar et QTabWidget QTabBar tab background qlineargradient spread pad x1 0
  • 使用信号和槽更新指针

    我对 Qt 很陌生 请帮我解决这个问题 我正在使用线程在后台执行密集操作 同时我想更新 UI 所以我使用 SIGNALS 和 SLOTS 为了更新 UI 我发出一个信号并更新 UI 让我们考虑下面的示例代码 struct sample QS
  • QGraphicsView 在完整布局中未最大化

    I have following GUI having four QGraphicView objects 正如您在每个视图下看到的那样 它有四个工具按钮 为了最大化视图 我连接了工具按钮的信号来隐藏其他三个视图的插槽 并将大小策略设置为扩
  • Qt ObjectName() 必须是唯一的吗?

    如标题所示的简单问题 如果我打电话setObjectName 在一个对象上 它是否必须是唯一的 或者只是因为约定而推荐 我已经子类化了QLabel 并希望自动为创建的对象命名 如果这是一个坏主意 我会找到一些设置随机唯一名称的方法 我实际上
  • QListWidget 拖放项目从 Symbian 列表中消失

    我在实现带有可通过拖放重新排序的自定义项的 QListWidget 时遇到问题 问题是当我在某个项目上快速双击 非常短的拖放 时 该项目有时会从 QListWidget 中消失 这是我的小部件的构造函数 ListPopisiDragDrop
  • PyQt QFileDialog exec_ 很慢

    我正在使用自定义QFileDialog因为我想选择多个目录 但是exec 功能非常慢 我不明白为什么 我正在使用最新版本的 PyQt 代码片段 from PyQt4 import QtGui QtCore QtNetwork uic cla
  • 关于在 Qt 中使用未记录的类

    使用无证文件是否安全QObjectUserData类和QObject setUserData in Qt 相反 你可以看看使用QObject setProperty http doc qt io qt 5 qobject html setP
  • 派生类在 PySide (Qt/PyQt) 中的错误线程中接收信号

    我在让派生类在 PySide 中正确接收信号时遇到问题 我在主 GUI 或命令行应用程序 线程的两个单独线程上使用发送器和接收器 线程是 QThread 对象 发送器和接收器在创建后立即使用 QObject moveToThread 移动到
  • 如何将 QByteArray 转换为十六进制字符串?

    我有打击QByteArray QByteArray ba ba 0 0x01 ba 1 0x10 ba 2 0x00 ba 3 0x07 我真的不知道如何将此 QByteArray 转换为结果字符串 其中包含 01100007 我将使用 Q
  • 无法在 QGLWidget 中设置所需的 OpenGL 版本

    我正在尝试在 Qt 4 8 2 中使用 QGLWidget 我注意到 QGLWidget 创建的默认上下文不显示 OpenGL 3 1 以上的任何输出 Qt wiki 有一个教程 http qt project org wiki How t

随机推荐

  • Canvas 基础使用

    一 基本的画布功能 创建
  • Verilog实现的SPI通信

    SPI Serial Peripheral Interface 串行外设接口 高速的 全双工 同步通信总线 SPI以主从方式工作 一般需要至少4根线 单向传输时可用3根 1 MISO Master Input Slave Output 主设
  • css修改浏览器默认滚动条样式

    滚动条样式 webkit scrollbar width 4px height 4px webkit scrollbar thumb border radius 10px webkit
  • Unity调用相机的方式总结

    1 通过C 即脚本 的方式调用相机 参考引用Unity调用摄像头功能简单实现方法 Unity代码调用摄像头 1 新建C 文件 此组件挂在一个物体上 可以是空物体或者camera 2 新建一个plane用于显示图像 利用该gameobject
  • 人脸识别:coco loss-Rethinking Feature Discrimination and Polymerization for Large-scale Recognition

    nips的一篇做分类和识别的工作 其中在人脸识别任务上也做了实验 Rethinking Feature Discrimination and Polymerization for Large scale Recognition Yu Liu
  • 设计模式:适配器模式

    适配器模式 即Adapter模式 又叫包装器Wrapper 用于改变已有类的接口形式 它可以将某个类的接口转换成客户端期望的另一个接口 主要目的是实现兼容性 让原本因接口不匹配不能一起工作的两个类可以协同工作 比如正常的电压是220v 插座
  • 【Kubernetes资源篇】StatefulSet无状态服务管理入门实战详解

    文章目录 一 StatefulSet理论知识 1 StatefulSet Pod控制器特性 2 什么是有状态服务和无状态服务 3 Deployment和StatefulSet区别 二 案例 StatefulSet资源实战演示 1 创建WEB
  • 解决CQ-HTTP无法远程登录的问题

    解决CQ HTTP无法远程登录的问题 前言 2022 6 3 第一步 准备 第二步 配置两端的go cqhttp 第三步 正文 前言 2022 6 3 相信自从酷Q无了后 很多人都了解到了go cqhttp这一优秀的qq机器人插件 但是在服
  • Django框架之搭建虚拟环境

    1 建立虚拟环境 pip install virtualenv 2 打开E盘创建文件夹名字为 aikun 3 进入文件夹中 shift 右击 打开Powershell 建立虚拟环境 4 输入 python m venv aikun env
  • HBase异常 -- KeeperErrorCode = ConnectionLoss for /hbase/hbaseid(单机)

    环境信息 虚拟机版本 centos7 HBase版本1 3 3 Hadoop版本 2 6 4 Zookeeper版本 3 4 5 异常信息 ERROR main zookeeper RecoverableZooKeeper ZooKeepe
  • AD域中组织单位和组的区别

    组和组织单元有很大的不同 组主要用于权限设置 而组织单元则主要用于网络构建 另外 组织单元只表示单个域中的对象集合 可包括组对象 而组可以包含用户 计算机 本地服务器上的共享资源 单个域 域目录树或目录林 组织单位是ou 组是group 前
  • GANs:生成对抗网络系列及应用

    GANs Goodfellow和Bengio等人发表在NIPS 2014年的文章Generative Adversarial Network是生成对抗网络的开创文章 论文思想启发自博弈论中的二人零和博弈 在二人零和博弈中 两位博弈放的利益之
  • 显示生成连续大小写字母

    9 生成连续大小写字母 package array 显示生成连续字母 public class array4 public static void main String args TODO Auto generated method st
  • java实现分页功能_Java实现简单的分页功能

    本文实例为大家分享了Java实现分页功能的具体代码 供大家参考 具体内容如下 不用根据改变SQL的形式去查询 直接查询所有的数据 根据页码自动显示数据 分页对象 public class PageUtils implements Seria
  • windows知识系列:硬软连接

    总结 创建硬连接 mklink H link 要关联的文件夹 创建软连接 mklink D link 要关联的文件夹 参考 硬 软连接 以及在windows中的用法
  • OPENCV4学习代码-Mat类构造与赋值

    代码清单2 4 默认构造函数使用方式 cv Mat Mat 代码清单2 5 利用矩阵尺寸和类型参数构造Mat类 cv Mat Mat int rows int cols int type 代码清单2 6 用Size 结构构造Mat类 cv
  • 华为机考笔记之字符串以水仙花规则拆分

    题目 一 输入一组字符串 求字符串分组后 每组的和为水仙花数 注 水仙花数是一个三位数 其个位 十位 百位的立次方 的和等于自身 如 371 3 3 7 3 1 1 1 如果无法找到该分组 返回0 2 找到该分组 切分组不唯一 返回 1 3
  • js 每隔 10 秒钟 运行一次,发送一个 ajax 请求

    每隔 10 秒钟 运行一次 发送一个 ajax 请求 function runEvery10Sec 1000 10 10 秒钟 setTimeout runEvery10Sec 1000 10 ajax dataType json type
  • jQuery取得select选中的值

    jQuery取得select选中的值 本来以为jQuery select1 val 是取得选中的值 那么jQuery select1 text 就是取得的文本 这是不正确的 正确做法是 jQuery select1 option selec
  • Qt中的单例模式:实现一个单例的界面类

    文章目录 前言 一 什么是单例模式 二 单例模式的优缺点及使用场景 三 Qt中单例类的创建 四 单例类的使用 测试 总结 前言 本文主要讲述了使用加锁的懒汉式来实现单例 文中示例将一个界面类修改为单例类 并在主界面获取多次该类的实例来进行测