当前位置: 首页 > news >正文

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>

相关文章:

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

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

备战蓝桥杯 Day6(学习动态规划)

引入 支付问题 假设有无限多的硬币&#xff0c;硬币面值为1,5,11。现在需要支付15元&#xff0c;问最少使用的硬币数&#xff1f; 贪心策略&#xff1a;1511*11*4&#xff0c;145 真正的答案153*5 3 dp的两个性质 最优子结构无后效性 dp的两大要素 1.状态2.状态转移方程 思路…...

【uniapp】自定义步骤条样式

代码实现 <view class"steps-wrap"><view class"flex-box"><view class"number active-number">1</view><view class"desc active-desc">步骤1</view><view :class"[line, activeStep …...

UE5 C++ UObject实例化

一.创建UObject C类 在MyObject中声明结构体FMyDataTableStruct 在MyPawn里面&#xff0c;先将头文件里包含 MyObject.h 在MyPawn中声明一个UMyObject类型的指针 TSubclassOf 是提供 UClass 类型安全性的模板类。例如您在创建一个投射物类&#xff0c;允许设计者指定伤害类型…...

Appium环境安装与架构介绍

Appium架构 Appium 设计哲学 不需要为了自动化而重新编译或修改被测应用不应该让移动端自动化测试限定在某种语言或者某个具体的框架不要为了移动端的自动化测试而重新造轮子移动端自动化测试应该是开源的 Appium 架构 Appium 架构图如下&#xff1a; Appium 的核心是一个 …...

Vue+Vite项目初建(axios+Unocss+iconify)

一. 创建项目 npx --package vue/cli vue 项目成功启动后&#xff0c;进入http://localhost:3200&#xff0c;即可进入创建好的页面(假设启动端口为3200) 二. 测试网络通讯模块 假设有本地服务器地址localhost:8000提供接口服务&#xff0c;接口为localhost:8000/token&#…...

ASUS华硕枪神8笔记本电脑G614JIR,G814JVR,G634JYR,G834JZR工厂模式出厂Windows11系统 带重置还原功能

适用ROG枪神8系列笔记本型号&#xff1a; G614JIR、G614JVR、G634JYR、G634JZR G814JIR、G814JVR、G834JYR、G834JZR 链接&#xff1a;https://pan.baidu.com/s/1tYZt6XFNC2d6YmwTbtFN7A?pwd3kp8 提取码&#xff1a;3kp8 带有ASUS RECOVERY恢复功能、自带所有驱动、出厂主…...

Python入门:常用模块—xml模块

xml是实现不同语言或程序之间进行数据交换的协议&#xff0c;跟json差不多&#xff0c;但json使用起来更简单 xml的格式如下&#xff0c;就是通过<>节点来区别数据结构的: <data> <country name"Liechtenstein"> <rank updated"yes"…...

蓝队应急响应工具箱v2024.1​

1 蓝队工具箱 v2024.1 2 简介 蓝队工具箱是为打造一款专业级应急响应的集成多种工具的工具集&#xff0c;由真实应急响应环境所用到的工具进行总结打包而来&#xff0c;由 ChinaRan404,W 啥都学,清辉等开发者编写.把项目现场中所用到的工具连同环境一同打包&#xff0c;并实…...

Linux中获取字符串长度与获取子字符串

一、 获取字符串长度 #!/bin/bash string"jobs" echo ${string} # 输出结果: jobs echo ${#string} # 输出结果: 4 二、提取子字符串 以下实例从字符串第 2 个字符开始截取 4 个字符&#xff1a; #!/bin/bash str"敢于亮剑决不后退" echo ${str:2:…...

Rust语言之sha-256爆破

文章目录 一、实现Sha-256加密1.创建项目2.编写Cargo.toml文件3.编写程序代码 二、sha256爆破1.获取命令行参数2.读取文件3.校验输入参数4.暴力破解 一、实现Sha-256加密 SHA-256是一种安全哈希算法&#xff0c;主要特点是将输入的数据&#xff08;无论长度&#xff09;通过特定…...

Rust中的字符串处理及相关方法详解

在Rust中&#xff0c;字符串是一种非常重要的数据类型&#xff0c;而String类型则提供了对动态可变字符串的支持。本文将介绍一些常见的字符串处理方法以及相关示例代码。 创建字符串 在Rust中&#xff0c;有多种方式创建字符串&#xff0c;以下是一些常见的例子&#xff1a;…...

NS安装-CentOS服务器安装Nightscout CGM

NS CGM 安装必要条件 有自己的云服务器好像没有2&#xff0c;有云服务器就行了 安装顺序 先安装数据库&#xff0c;目前支持的是 MongoDB &#xff0c;官方推荐4&#xff0c;其实目前最新版本就行。可以用宝塔安装&#xff0c;比较简单克隆代码&#xff0c;我是放到 /opt/ns…...

利用ChatGPT提升工作效率

随着科技的飞速发展&#xff0c;人工智能逐渐成为我们生活的一部分。ChatGPT作为一种先进的自然语言处理技术&#xff0c;已经在各个领域取得了显著的成果。本文将探讨如何利用ChatGPT提升工作效率&#xff0c;让我们的生活变得更加便捷。 一、什么是ChatGPT&#xff1f; ChatG…...

django admin页面美化

美化 Django Admin 页面可以通过多种方式实现&#xff0c;从简单的 CSS 样式调整到完全自定义模板。以下是一些建议和步骤来美化 Django Admin 页面&#xff1a; 1. 使用 CSS 覆盖默认样式 这是最简单的方法&#xff0c;你可以通过添加自定义 CSS 文件来覆盖 Django Admin 的…...

Git 操作以及Git 常见问题

Git 操作 git 教程&#xff1a;https://www.runoob.com/git/git-tutorial.html 基本概念 工作区&#xff1a;克隆项目到本地后&#xff0c;项目所在的文件夹&#xff1b; 暂存区&#xff1a;从工作区添加上来的变更&#xff08;新增&#xff0c;修改&#xff0c;删除&#xff…...

如何学习和规划类似ChatGPT这种人工智能(AI)相关技术

学习和规划类似ChatGPT这种人工智能&#xff08;AI&#xff09;相关技术的路径通常包括以下步骤&#xff1a; 学习基础知识&#xff1a; 学习编程&#xff1a;首先&#xff0c;你需要学习一种编程语言&#xff0c;例如Python&#xff0c;这是大多数人工智能项目的首选语言。数学…...

4 月 9 日至 4 月 10 日,Hack.Summit() 2024 首聚香江

Hack.Summit() 是一系列 Web3 开发者大会。2024 年的活动将于 2024 年 4 月 9 日至 4 月 10 日在香港数码港举行。自十年前首次举办以来&#xff0c;此次会议标志着 Hack.Summit() 首次在亚洲举办&#xff0c;香港被选为首次亚洲主办城市&#xff0c;这对 Hack VC 和该地区都具…...

[力扣 Hot100]Day29 删除链表的倒数第 N 个结点

题目描述 给你一个链表&#xff0c;删除链表的倒数第 n 个结点&#xff0c;并且返回链表的头结点。 出处 思路 两个指针间隔n&#xff0c;一趟遍历解决。 代码 class Solution { public:ListNode* removeNthFromEnd(ListNode* head, int n) {ListNode* phead;ListNode* …...

探索设计模式的魅力:掌握命令模式-解锁软件设计的‘遥控器’

​&#x1f308; 个人主页&#xff1a;danci_ &#x1f525; 系列专栏&#xff1a;《设计模式》 &#x1f4aa;&#x1f3fb; 制定明确可量化的目标&#xff0c;并且坚持默默的做事。 引言&#xff1a;探索命令模式的奥秘 软件设计领域充满挑战与机遇&#xff0c;命令模式…...

突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合

强化学习&#xff08;Reinforcement Learning, RL&#xff09;是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程&#xff0c;然后使用强化学习的Actor-Critic机制&#xff08;中文译作“知行互动”机制&#xff09;&#xff0c;逐步迭代求解…...

R语言AI模型部署方案:精准离线运行详解

R语言AI模型部署方案:精准离线运行详解 一、项目概述 本文将构建一个完整的R语言AI部署解决方案,实现鸢尾花分类模型的训练、保存、离线部署和预测功能。核心特点: 100%离线运行能力自包含环境依赖生产级错误处理跨平台兼容性模型版本管理# 文件结构说明 Iris_AI_Deployme…...

大型活动交通拥堵治理的视觉算法应用

大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动&#xff08;如演唱会、马拉松赛事、高考中考等&#xff09;期间&#xff0c;城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例&#xff0c;暖城商圈曾因观众集中离场导致周边…...

2024年赣州旅游投资集团社会招聘笔试真

2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...

spring:实例工厂方法获取bean

spring处理使用静态工厂方法获取bean实例&#xff0c;也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下&#xff1a; 定义实例工厂类&#xff08;Java代码&#xff09;&#xff0c;定义实例工厂&#xff08;xml&#xff09;&#xff0c;定义调用实例工厂&#xff…...

什么是EULA和DPA

文章目录 EULA&#xff08;End User License Agreement&#xff09;DPA&#xff08;Data Protection Agreement&#xff09;一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA&#xff08;End User License Agreement&#xff09; 定义&#xff1a; EULA即…...

LLM基础1_语言模型如何处理文本

基于GitHub项目&#xff1a;https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken&#xff1a;OpenAI开发的专业"分词器" torch&#xff1a;Facebook开发的强力计算引擎&#xff0c;相当于超级计算器 理解词嵌入&#xff1a;给词语画"…...

Unit 1 深度强化学习简介

Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库&#xff0c;例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体&#xff0c;比如 SnowballFight、Huggy the Do…...

聊一聊接口测试的意义有哪些?

目录 一、隔离性 & 早期测试 二、保障系统集成质量 三、验证业务逻辑的核心层 四、提升测试效率与覆盖度 五、系统稳定性的守护者 六、驱动团队协作与契约管理 七、性能与扩展性的前置评估 八、持续交付的核心支撑 接口测试的意义可以从四个维度展开&#xff0c;首…...

HDFS分布式存储 zookeeper

hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架&#xff0c;允许使用简单的变成模型跨计算机对大型集群进行分布式处理&#xff08;1.海量的数据存储 2.海量数据的计算&#xff09;Hadoop核心组件 hdfs&#xff08;分布式文件存储系统&#xff09;&a…...