Qt使用单例模式读取xml文件

Qt使用单例模式读取xml文件

  • 一、单例模式介绍
    • 1、什么是单例模式
    • 2、为什么使用单例模式
    • 3、什么情况下使用单例模式
    • 4、使用单例模式需要注意哪些问题
        • 线程安全
    • 5、单例模式的类型
    • 6、单例类的特点
  • 2、单例模式的实现
    • 2.1懒汉式
    • 2.2饿汉式

一、单例模式介绍

1、什么是单例模式

单例模式是指在整个系统生命周期内,保证一个类只能产生一个实例,确保该类的唯一性。

2、为什么使用单例模式

1、节省资源。一个类只有一个实例,不存在多份实例,节省资源。
2、方便控制。在一些操作公共资源的场景时,避免了多个对象引起的复杂操作。

3、什么情况下使用单例模式

在程序中多次使用同一个对象且作用相同时,为了防止频繁地创建对象使得内存飙升,单例模式可以让程序仅在内存中创建一个对象,让所有需要调用的地方都共享这一单例对象。

4、使用单例模式需要注意哪些问题

线程安全
  • 什么是线程安全

在拥有共享数据的多条线程并行执行的程序中,线程安全的代码会通过同步机制保证各个线程都可以正常且正确的执行,不会出现数据污染等意外情况。

  • 如何保证线程安全

1、给共享的资源加把锁,保证每个资源变量每时每刻至多被一个线程占用。
2、让线程也拥有资源,不用去共享进程中的资源。如:使用threadlocal可以为每个线程维护一个私有的本地变量。

5、单例模式的类型

  • 懒汉式

系统运行中,实例并不存在,只有当需要使用该实例时,才会去创建并使用实例。这种方式要考虑线程安全。

  • 饿汉式

系统一运行,就初始化创建实例,当需要时,直接调用即可。这种方式本身就线程安全,没有多线程的线程安全问题。

6、单例类的特点

  • 构造函数和析构函数为私有类型,目的是禁止外部构造和析构。
  • 拷贝构造函数和赋值构造函数是私有类型,目的是禁止外部拷贝和赋值,确保实例的唯一性。
  • 类中有一个获取实例的静态方法,可以全局访问。

2、单例模式的实现

2.1懒汉式

Created with Raphaël 2.3.0 开始 使用单例对象 单例对象是否实例化? 返回单例对象 实例化单例对象 yes no

加锁的懒汉式单例(线程安全)
头文件:

///  加锁的懒汉式实现  //class SingleInstance
{public:// 获取单实例对象static SingleInstance *GetInstance();//释放单实例,进程退出时调用static void deleteInstance();//返回所有的IPQVariantList getIP(){return m_ips;}//获取XML文件bool initalize();// 打印实例地址void Print();private:// 将其构造和析构成为私有的, 禁止外部构造和析构SingleInstance();~SingleInstance();// 将其拷贝构造和赋值构造成为私有函数, 禁止外部拷贝和赋值SingleInstance(const SingleInstance &signal);const SingleInstance &operator=(const SingleInstance &signal);//解析xml中的内容void parseIP(const QDomNode &root);private:// 唯一单实例对象指针static SingleInstance *m_SingleInstance;static std::mutex m_Mutex;//存储IPQVariantList m_ips;
};

源文件:

//初始化静态成员变量
SingleInstance *SingleInstance::m_SingleInstance = nullptr;
std::mutex SingleInstance::m_Mutex;// 注意:不能返回指针的引用,否则存在外部被修改的风险!
SingleInstance * SingleInstance::GetInstance()
{//  这里使用了两个 if 判断语句的技术称为双检锁;好处是,只有判断指针为空的时候才加锁,//  避免每次调用 GetInstance的方法都加锁,锁的开销毕竟还是有点大的。if (m_SingleInstance == nullptr) {std::unique_lock<std::mutex> lock(m_Mutex); // 加锁if (m_SingleInstance == nullptr){volatile auto temp = new (std::nothrow) SingleInstance();m_SingleInstance = temp;}}return m_SingleInstance;
}void SingleInstance::deleteInstance()
{std::unique_lock<std::mutex> lock(m_Mutex); // 加锁if (m_SingleInstance){delete m_SingleInstance;m_SingleInstance = nullptr;}
}bool SingleInstance::initalize()
{QString path("目录");QFile file(path);if(file.exists()){if(file.open(QIODevice::ReadOnly | QIODevice::Truncate)){QString error;QDomDocument document;document.setContent(&file, &error);file.close();if(document.isNull()){qDebug() << QString("文件格式异常:1%").arg(error);return false;}QDomNode root = document.firstChild();parseIP(root);}else{qDebug() << QString("%1:文件不存在,:2%").arg(path).arg(file.errorString());}}else{qDebug() QString("%1:文件不存在!").arg(path);return false;}return !m_ips.isEmpty();
}void SingleInstance::Print()
{std::cout << "我的实例内存地址是:" << this << std::endl;
}SingleInstance::SingleInstance()
{std::cout << "构造函数" << std::endl;
}SingleInstance::~SingleInstance()
{std::cout << "析构函数" << std::endl;deleteInstance();
}void SingleInstance::parseIP(const QDomNode &root)
{QDomNode startnode = root.nextSibling();QDomNode node = startnode.firstChild();while(!node.isNull()){QVariantMap ips;ips.clear();QDomElement element = node.toElement();ips.insert("ip", element.attribute("ip"));ips.insert("port", element.attribute("port"));ips.insert("multiip", element.attribute("multiip"));}}

main.cpp

if(Singleton::GetInstance()->initalize())
{
...
}

2.2饿汉式

头文件

// 饿汉实现 /class Singleton
{
public:// 获取单实例static Singleton* GetInstance();// 释放单实例,进程退出时调用static void deleteInstance();//返回所有的IPQVariantList getIP(){return m_ips;}//获取XML文件bool initalize();// 打印实例地址void Print();private:// 将其构造和析构成为私有的, 禁止外部构造和析构Singleton();~Singleton();// 将其拷贝构造和赋值构造成为私有函数, 禁止外部拷贝和赋值Singleton(const Singleton &signal);const Singleton &operator=(const Singleton &signal);//解析xml中的内容void parseIP(const QDomNode &root);private:// 唯一单实例对象指针static Singleton *g_pSingleton;//存储IPQVariantList m_ips;
};

源文件:

// 代码一运行就初始化创建实例 ,本身就线程安全
Singleton* Singleton::g_pSingleton = new (std::nothrow) Singleton();Singleton* Singleton::GetInstance()
{return g_pSingleton;
}void Singleton::deleteInstance()
{if (g_pSingleton){delete g_pSingleton;g_pSingleton = nullptr;}
}bool SingleInstance::initalize()
{QString path("目录");QFile file(path);if(file.exists()){if(file.open(QIODevice::ReadOnly | QIODevice::Truncate)){QString error;QDomDocument document;document.setContent(&file, &error);file.close();if(document.isNull()){qDebug() << QString("文件格式异常:1%").arg(error);return false;}QDomNode root = document.firstChild();parseIP(root);}else{qDebug() << QString("%1:文件不存在,:2%").arg(path).arg(file.errorString());}}else{qDebug() QString("%1:文件不存在!").arg(path);return false;}return !m_ips.isEmpty();
}void Singleton::Print()
{std::cout << "我的实例内存地址是:" << this << std::endl;
}Singleton::Singleton()
{std::cout << "构造函数" << std::endl;
}Singleton::~Singleton()
{std::cout << "析构函数" << std::endl;deleteInstance();
}void SingleInstance::parseIP(const QDomNode &root)
{QDomNode startnode = root.nextSibling();QDomNode node = startnode.firstChild();while(!node.isNull()){QVariantMap ips;ips.clear();QDomElement element = node.toElement();ips.insert("ip", element.attribute("ip"));ips.insert("port", element.attribute("port"));ips.insert("multiip", element.attribute("multiip"));}}

main.cpp

if(Singleton::GetInstance()->initalize())
{
...
}

xml说明

<?xml version="1.0" encoding="utf-8"?>XML声明是XML文档的第一句
<ips>
<ip ip="xxx" port="xxx" multiip="xxx"/>
</ips>

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在Linux系统中设置HTTP隧道以实现网络穿透和端口转发

在数字化世界中&#xff0c;网络穿透和端口转发成为了许多开发者和系统管理员必备的技能。而在Linux系统中&#xff0c;通过设置HTTP隧道&#xff0c;我们可以轻松实现这一目标&#xff0c;让我们的服务即便在内网环境中也能被外部世界所访问。 那么&#xff0c;如何在Linux系…

一文搞懂设计模式—观察者模式

本文已收录至Github&#xff0c;推荐阅读 &#x1f449; Java随想录 微信公众号&#xff1a;Java随想录 文章目录 使用场景实现方式Java对观察者模式的支持Guava对观察者模式的支持Spring对观察者模式的支持 优缺点 观察者模式&#xff08;Observer Pattern&#xff09;是一种…

小型洗衣机哪个牌子质量好?小型洗衣机十大排名

清洗内衣内裤这些贴身衣物确实是一件比较头疼的事&#xff0c;有的小伙子由于工作的劳累通常在洗完澡后并不喜欢直接清洗内衣内裤&#xff0c;会存上几天再扔到洗衣机里&#xff0c;这样做是很不可取的&#xff0c;因为穿过的内裤很久不洗就会滋生细菌&#xff0c;另外&#xf…

Java使用Documents4j实现Word转PDF(知识点+案例)

文章目录 前言源码获取一、认识Documents4j二、快速集成2.1、pom.xml依赖2.2、word转PDF实现项目目录WordUtils.javaDemo6.java测试效果 参考文章资料获取 前言 博主介绍&#xff1a;✌目前全网粉丝2W&#xff0c;csdn博客专家、Java领域优质创作者&#xff0c;博客之星、阿里…

CSS的伪类选择器:nth-child()的用法示例

CSS的伪类选择器:nth-child()的用法示例 n可以- , 右边数字只能 第一到第六的td : td:nth-child(n1):nth-child(-n6) td:nth-child(n1):nth-child(-n6)第二到第八的a : a:nth-child(n2):nth-child(-n8) a:nth-child(n2):nth-child(-n8)1等效0n1 , 7等效0n7 , 没有负数,不能…

使用 C++23 从零实现 RISC-V 模拟器(6):权限支持

本节内容增加了权限表示&#xff0c;设置了三种权限。当 cpu 初始化时默认的权限为 Machine 模式。接下来实现这三种特权模式&#xff0c;随后实现 sret 和 mret 指令。 RISC-V定义了三种特权等级&#xff0c;分别是用户态&#xff08;User Mode&#xff09;、监管态&#xff…

Linux-系统资源管理的命令

目录 查看CPU&#xff1a;more /proc/meminfo 查看内存数据&#xff1a;free -m / free -h 查看系统版本&#xff1a;more /etc/issue 查看操作系统的类型&#xff1a;uname -a 查看主机名称&#xff1a;hostname 查看磁盘空间&#xff1a;df -h 查看某个目录空间…

【解决(几乎)任何机器学习问题】:处理分类变量篇(上篇)

这篇文章相当长&#xff0c;您可以添加至收藏夹&#xff0c;以便在后续有空时候悠闲地阅读。 本章因太长所以分为上下篇来上传&#xff0c;请敬请期待 很多⼈在处理分类变量时都会遇到很多困难&#xff0c;因此这值得⽤整整⼀章的篇幅来讨论。在本章中&#xff0c;我将 讲述不同…

快速搞懂时间序列数据平稳检验

在对时间序列数据进行分析预测时&#xff0c;平稳时间序列数据预测效果更好。所以首先要检测数据是否平稳&#xff0c;没有趋势的时间序列数据&#xff0c;我们称为平稳的&#xff0c;即随着时间的推移&#xff0c;表现出恒定的方差&#xff0c;具有恒定的自相关结构。本文介绍…

Linux 虚拟机在线热扩容分区

介绍 本教程是用于Linux虚拟机在调整虚拟硬盘大小后&#xff0c;进行在线不重启热扩容分区大小。 适用于RHEL 7以上的版本及衍生发行版。&#xff08;如Centos、Rocky Linux、Alma Linux等&#xff09; 硬盘分区在线热扩容 刷新硬盘容量 echo 1 > /sys/block/sda/device…

GIS利用不舒适指数绘制地区的生物气候舒适度图

生物气候舒适度定义了最适宜的气候条件,在这种条件下,人们感到健康和充满活力。生物气候舒适度地图对城市规划研究特别有用。温度、相对湿度和风速等要素对评估生物气候舒适度非常重要。[1] 人们已经得出了许多不同的指数来确定生物气候舒适度。在本博文中,我们将使用广泛使…

C++基于多态的职工管理系统完整代码

1.头文件.h 部分&#xff1a; 1.1 Worker.h /*这是一个抽象的职工父类&#xff0c;以下类都继承自该类&#xff1a;1.Employee类 2.Manager类 3.Boss类 */#pragma once #include<iostream> #include<string> using namespace std; //使用标准命名空间 class W…

Elcomsoft 取证工具包系列:Advanced Office Password Recovery

天津鸿萌科贸发展有限公司是 Elcomsoft 系列软件授权代理商。 Advanced Office Password Recovery 是 Elcomsoft 取证工具包中的密码破解软件之一。它可以恢复、删除或规避使用各种 Office 套件创建的文档的密码。可以对 WordPerfect&#xff0c;Lotus&#xff0c;OpenOffice&…

[晓理紫]每日论文分享(有中文摘要,源码或项目地址)--大模型、扩散模型等

专属领域论文订阅 VX关注{晓理紫}&#xff0c;每日更新论文&#xff0c;如感兴趣&#xff0c;请转发给有需要的同学&#xff0c;谢谢支持 如果你感觉对你有所帮助&#xff0c;请关注我&#xff0c;每日准时为你推送最新论文。 为了答谢各位网友的支持&#xff0c;从今日起免费为…

深入浅出 Python 函数:编写、使用与高级特性详解

引言 在 Python 编程的世界中,函数堪称构建复杂逻辑和模块化程序的基础砖石。它能够帮助程序员组织代码、避免重复,并通过封装逻辑提高代码的可读性和可维护性。本文旨在全方位解析 Python 函数的核心概念,包括基础定义、文档化、默认参数、可选参数、解包参数、关键字仅参…

普中51单片机学习(七)

LED闪烁 delay函数 延时函数 void delay(unsigned int i)//大约延时10us {while(i--); }实验代码 #include "reg52.h" typedef unsigned char u8; typedef unsigned int u16;void delay(u16 i) {while(i--); } sbit ledP2^0;void main(){while(1){led0;delay(10…

深入解析域名短链接生成原理及其在Python/Flask中的实现策略:一篇全面的指南与代码示例

为了构建一个高效且用户友好的域名短链服务&#xff0c;我们可以将项目精简为以下核心功能板块&#xff1a; 1. 用户管理 注册与登录&#xff1a;允许用户创建账户并登录系统。 这部分内容可以参考另一片文章实现&#xff1a; 快速实现用户认证&#xff1a;使用Python和Flask…

【c++设计模式03】创建型1:简单工厂模式(Simple Factory Pattern)

【c设计模式03】创建型1&#xff1a;简单工厂模式&#xff08;Simple Factory Pattern&#xff09; 一、工厂模式二、简单工厂模式三、UML类图四、demo五、使用多态的简单工厂模式1、UML类图——使用多态2、demo——使用多态 原创作者&#xff1a;郑同学的笔记 原创地址&#x…

GAN:“左右互搏”的卷积网络,不断优化性能中

hello宝子们...我们是艾斯视觉擅长ui设计和前端开发10年经验&#xff01;希望我的分享能帮助到您&#xff01;如需帮助可以评论关注私信我们一起探讨&#xff01;致敬感谢感恩&#xff01; 在一个名为“卷王”的世界里&#xff0c;有一个传奇般的存在——生成对抗网络&#xff…

解释器设计模式

解释器设计模式&#xff08;Interpreter Pattern&#xff09;是一种行为型设计模式&#xff0c;它定义了一种语言的文法&#xff0c;并建立一个解释器来解释该语言中的句子。这种模式通常用于需要解释或执行一种特定类型的语言的场景&#xff0c;例如编程语言的编译器或解释器、…