Qt 智能指针
Qt 智能指针
文章目录
- Qt 智能指针
- `QScopedPointer`
- 1. 自动删除对象
- 2. 转移所有权
- 3. 管理私有数据
- `QSharedPointer`
- 关键特性
- 注意事项
- `QWeakPointer`
- 注意事项
- `QPointer`
QScopedPointer
QScopedPointer 是 Qt 提供的一个智能指针,主要用于简化资源管理,防止内存泄漏和悬挂指针问题。它属于 Qt 的内存管理工具,能够自动处理对象的生命周期,确保对象在超出作用域时被销毁。QScopedPointer 是基于 C++11 标准中的 std::unique_ptr 实现的,但它具有 Qt 的特点,通常用于局部对象的管理。
- 自动删除对象:当
QScopedPointer超出作用域时,它会自动释放所持有的对象。这意味着无需手动delete对象。 - 不能复制:
QScopedPointer不支持复制操作,防止发生意外的多个指针指向同一个对象的问题。 - 所有权转移:可以使用
reset()或通过构造函数将QScopedPointer的所有权转移给另一个QScopedPointer。
1. 自动删除对象
QScopedPointer 最常见的用法是在函数或局部作用域内管理动态分配的对象。在作用域结束时,QScopedPointer 自动销毁对象,无需显式调用 delete。
#include <QScopedPointer>
#include <QDebug>class MyClass {
public:MyClass() { qDebug() << "MyClass constructed"; }~MyClass() { qDebug() << "MyClass destructed"; }
};void testScopedPointer() {QScopedPointer<MyClass> ptr(new MyClass);// 当函数返回时,ptr 超出作用域,对象会被自动销毁
} // 在这里,MyClass 对象会被自动删除
2. 转移所有权
QScopedPointer 不支持复制操作,但可以通过 reset() 或构造函数转移所有权。这样,QScopedPointer 可以在不同的作用域之间传递资源。
#include <QScopedPointer>
#include <QDebug>class MyClass {
public:MyClass() { qDebug() << "MyClass constructed"; }~MyClass() { qDebug() << "MyClass destructed"; }
};void transferOwnership() {QScopedPointer<MyClass> ptr1(new MyClass);// 将所有权从 ptr1 转移到 ptr2QScopedPointer<MyClass> ptr2(ptr1.take());// 现在 ptr1 不再拥有 MyClass 对象,ptr2 拥有它// ptr1 不再指向对象,但对象仍然存在,由 ptr2 管理
} // 在这里,ptr2 超出作用域时,MyClass 对象会被自动删除
3. 管理私有数据
在 Qt 的许多类中,私有数据(通常是一个包含实现细节的类)被封装在一个 QScopedPointer 中。这样可以确保私有数据在类的析构函数中自动释放,同时保持代码的简洁性和安全性。
示例:QFile 类
class QFilePrivate : public QIODevicePrivate {// 私有数据成员
};class QFile : public QIODevice {
public:QFile();~QFile();private:QScopedPointer<QFilePrivate> d_ptr;
};
在这个例子中,QFile 类使用 QScopedPointer 来管理 QFilePrivate 对象。当 QFile 对象析构时,QScopedPointer 会自动删除 QFilePrivate 对象,确保内存被释放。
QSharedPointer
QSharedPointer 是通过引用计数来管理对象的生命周期的,多个 QSharedPointer 对象可以共享同一个资源。每当 QSharedPointer 的拷贝构造或赋值操作发生时,引用计数会增加,而当一个 QSharedPointer 被销毁时,引用计数会减少。当引用计数降到 0 时,所指向的对象会自动被删除。
#include <QSharedPointer>
#include <QDebug>class MyClass {
public:void print() { qDebug() << "Hello from MyClass!"; }
};int main() {// 创建 QSharedPointer 对象,管理 MyClass 对象的生命周期QSharedPointer<MyClass> ptr1(new MyClass);// 创建另外一个 QSharedPointer,并共享 ptr1 所管理的对象QSharedPointer<MyClass> ptr2 = ptr1;// 使用 ptr1 和 ptr2 都能访问同一个对象ptr1->print();ptr2->print();// 不需要手动释放内存,当最后一个 QSharedPointer 被销毁时,MyClass 对象会自动删除return 0;
}
关键特性
- 引用计数:
QSharedPointer通过引用计数来管理对象的生命周期。每当有新的QSharedPointer对象指向相同的资源时,引用计数会增加;当某个QSharedPointer对象销毁时,引用计数会减少。 - 自动销毁:当最后一个引用计数为 1 的
QSharedPointer被销毁时,指向的对象会被自动删除,从而避免了内存泄漏。 - 线程安全:
QSharedPointer的引用计数操作是线程安全的,但它本身并不保证被指向的对象本身是线程安全的。如果多个线程访问同一个QSharedPointer对象,必须确保其他线程同步访问该对象。
注意事项
QSharedPointer的引用计数机制在某些情况下可能导致循环引用问题,特别是当两个或更多的对象相互持有对方的QSharedPointer时。此时,即使这些对象不再使用,引用计数也不会降到零,因为它们互相引用,导致对象无法被销毁,从而产生内存泄漏。- 解决方法:使用
QWeakPointer来打破循环引用。QWeakPointer是一种弱引用,持有一个QSharedPointer对象,但它不会增加引用计数。当QSharedPointer被销毁时,QWeakPointer自动变为空指针。
- 解决方法:使用
- 不要混用裸指针和
QSharedPointer``QSharedPointer需要确保它是唯一的内存管理者。如果你在程序中同时使用裸指针和QSharedPointer管理相同的内存,可能会导致双重释放或内存泄漏。因此,避免裸指针与智能指针共享同一资源,确保对象始终由智能指针管理。
QWeakPointer
QWeakPointer 是 QSharedPointer 的一种补充,它本身不拥有对象的所有权。QWeakPointer 仅在 QSharedPointer 的引用计数为非零时提供访问该对象的能力,但不会阻止对象的销毁。换句话说,QWeakPointer 允许你引用一个对象而不会使得该对象无法销毁。
QWeakPointer 的主要特点:
- 弱引用:
QWeakPointer不增加对象的引用计数,也就是说它不会阻止对象的销毁。 - 防止循环引用:
QWeakPointer解决了QSharedPointer可能导致的循环引用问题。 - 安全的访问方式:
QWeakPointer可以通过toStrongRef()方法转换为QSharedPointer,从而安全地访问目标对象。
QWeakPointer 和 QSharedPointer 的配合
QWeakPointer 通常与 QSharedPointer 一起使用,用于避免循环引用。在有些情况下,两个对象会互相引用,导致它们的引用计数始终不为零,进而导致内存泄漏。QWeakPointer 可以打破这个循环引用链,它允许对象 A 持有对象 B 的 QWeakPointer,而对象 B 可以持有对象 A 的 QSharedPointer,从而确保对象 A 和 B 的生命周期由 QSharedPointer 管理。
QWeakPointer 的常见用法
下面是一个使用 QWeakPointer 的具体示例:
class B; // Forward declarationclass A {
public:QSharedPointer<B> b; // B的共享指针
};class B {
public:QWeakPointer<A> a; // A的弱引用
};int main() {QSharedPointer<A> a(new A); // 创建A对象QSharedPointer<B> b(new B); // 创建B对象a->b = b; // A持有B的共享指针b->a = a; // B持有A的弱引用return 0; // 程序退出时,A和B会被自动销毁,避免内存泄漏
}
注意事项
使用QWeakPointer时候,一定要使用isNULL判断一下 资源是否释放
QSharedPointer<MyClass> shared(new MyClass(20));
QWeakPointer<MyClass> weak(shared);qDebug() << "Shared pointer value:" << shared->getValue();
qDebug() << "Weak pointer value:" << weak.data()->getValue();shared.clear(); // 删除 shared 指向的对象
// 此时,MyClass 对象的引用计数为 0,将被自动删除,而此时 QWeakPointer 对象 weak 也为 null。if (weak.isNull()) { // 判断 weak 是否为 nullqDebug() << "Weak pointer is null - object has been deleted"; // 执行
}
else {qDebug() << "Weak pointer is not null - object still exists";
}
QPointer
QPointer 是一个用于指向 Qt 对象(例如 QObject 的子类)的模板类,它会自动管理对象的生命周期。当一个 QObject 被销毁时,QPointer 会将其指针设为 nullptr,这使得程序能够检测到所指向的对象已经被删除,从而避免访问已删除的对象,避免悬空指针问题。QPointer 只能用来管理 QObject 或其子类的对象。如果你需要管理其他类型的对象,可以考虑使用其他智能指针,如 std::shared_ptr 或 std::unique_ptr。
#include <QPointer>
#include <QPushButton>
#include <QVBoxLayout>
#include <QWidget>
#include <QDebug>int main(int argc, char *argv[]) {QCoreApplication a(argc, argv);QWidget window;QVBoxLayout *layout = new QVBoxLayout(&window);QPushButton *button = new QPushButton("Click me");QPointer<QPushButton> pButton(button);layout->addWidget(button);window.show();QObject::connect(button, &QPushButton::clicked, [&] {if (pButton) {qDebug() << "Button exists, text:" << pButton->text();} else {qDebug() << "Button has been deleted";}});// 模拟按钮删除QObject::connect(button, &QPushButton::clicked, [&] {delete button;});return a.exec();
}
相关文章:
Qt 智能指针
Qt 智能指针 文章目录 Qt 智能指针QScopedPointer1. 自动删除对象2. 转移所有权3. 管理私有数据 QSharedPointer关键特性注意事项 QWeakPointer注意事项 QPointer QScopedPointer QScopedPointer 是 Qt 提供的一个智能指针,主要用于简化资源管理,防止内…...
CODESYS MODBUS TCP通信(禾川Q1 PLC作为MODBUS TCP从站)
禾川Q1 PLC MODBUS TCP 通信(PLC作为MODBUS TCP通信主站) 禾川Q1 PLC MODBUS TCP通信(CODESYS平台完整配置+代码)-CSDN博客文章浏览阅读28次。MATLAB和S7-1200PLC水箱液位高度PID控制联合仿真(MODBUSTCP通信)_将matlab仿真导入plc-CSDN博客文章浏览阅读722次。本文详细介绍了如…...
10.STM32F407ZGT6-内部温度传感器
参考: 1.正点原子 前言: 本笔记的主要目的和意义就是,再次练习ADC的使用。 32.1 内部温度传感器简介 STM32F407 有一个内部的温度传感器,可以用来测量 CPU 及周围的温度(TA)。对于STM32F407 系列来说,该温度传感器在…...
运维安全中心(堡垒机)
阿里云运维安全中心(Alibaba Cloud Operation and Maintenance Security, OMS,通常也称为“堡垒机”)是一款针对云上运维管理的安全解决方案。它专注于加强云环境中运维过程的安全性,确保对关键云资源和服务的访问可控、可审计&am…...
Linux OOM | Early OOM | 进程监视
注: 本文为 “Linux OOM” 相关文章合辑。 Linux OOM 终结者 译者:花名有孚 | 2015-07-21 08:47 现在是早晨 6 点钟。已经醒来的我正在总结到底是什么事情使得我的起床闹铃提前了这么多。我们的监控系统显示,Plumbr 服务出故障了。 现在我…...
【2024年华为OD机试】(A卷,100分)- 等和子数组最小和(Java JS PythonC/C++)
一、问题描述 题目描述 给定一个数组nums,将元素分为若干个组,使得每组和相等,求出满足条件的所有分组中,组内元素和的最小值。 输入描述 第一行输入 m 接着输入m个数,表示此数组nums 数据范围:1<m&…...
NFS服务
nfs文件系统 NFS:NetworkFileSystem网络文件系统,基于内核的文件系统。 服务安装 不固定端口启动,会注册到rpcbind(固定端口)服务上, 局域网适用[rootvm ~]# yum -y install nfs-utils # 依赖安装rpcbind [ro…...
RabbitMQ 交换机、队列和路由键的命名规范
在 RabbitMQ 中,使用 Topic Exchange 模式时,交换机、队列和路由键的命名规范是非常重要的,尤其是在多环境和多微服务的场景中。合理的命名规范可以提高消息系统的可维护性、可扩展性以及可读性。以下是一些关于 Topic Exchange 模式中交换机…...
腾讯云AI代码助手编程挑战赛-刑说
作品简介 鉴于当代普法力度不够大,这个刑说可以帮助大家更好的普及法律知识 技术架构 采用了全后端分离的架构,前端使用Vue.js,腾讯云的AI服务处理自然语言理解与生成。 实现过程 开发环境、开发流程 系统:win11 开发工具&…...
【测试】持续集成CI/CD
近期更新完毕,建议关注收藏点赞~ 目录 概括gitJenkinspostman集成jenkins代码集成jenkins 概括 CI/CD stands for Continuous Integration and Continuous Deployment 定义 团队成果持续集成到公共平台。一天可以集成1次or多次 本地代码管理 git 远程代…...
阿里云直播Web
官方文档:Web播放器SDK常见问题_视频点播(VOD)-阿里云帮助中心 bug:播流的不稳定,直播总会进入 onM3u8Retry 监听,用户端就会黑屏,(但其实并没有关播,正常关播进入的是pause这个监听࿰…...
DuckDB:PRAGMA语句动态配置数据库行为
PRAGMA语句是DuckDB从SQLite中采用的SQL扩展。PRAGMA命令可能会改变数据库引擎的内部状态,并可能影响引擎的后续执行或行为。本文介绍PRAGMA命令及其典型应用场景。 DuckDB PRAGMA介绍 在 DuckDB 中,PRAGMA 是一种编译指示(compiler directi…...
GO通过SMTP协议发送邮件
什么是SMTP协议 SMTP(Simple Mail Transfer Protocol,简单邮件传输协议)是用于发送邮件的协议。当一个邮件服务器需要发送邮件给另一个邮件服务器时,它会使用SMTP协议与目标服务器建立连接,并传输邮件内容。SMTP协议的…...
轻量自高斯注意力机制LSGAttention模型详解及代码复现
模型背景 近年来,卷积神经网络(CNN)在高光谱图像分类领域取得了显著进展。然而,CNN面临 长距离关系建模 和 计算成本 增加的挑战。为解决这些问题,研究人员提出了基于 轻量自高斯注意(Light Self-Gaussian-Attention, LSGA) 机制的视觉转换器(Vision Transformer, VIT),旨…...
解读若依框架中的`@Excel` 和 `@Excels` 注解
文章目录 一、Excels 注解详解1.1 适用场景1.2 作用与好处 二、Excel 注解详解2.1 核心属性解析2.2 高级用法2.3 综合应用案例 三、总结 解读若依框架中的 Xss 注解博客:解读若依框架中的 Xss 注解 接下来我们将对若依框架中的 Excel 和 Excels 注解进行更加详细的…...
云商城--基础数据处理和分布式文件存储
第2章 基础数据处理和分布式文件存储 1.分布式文件存储系统Ceph学习 1).掌握Ceph架构 2).掌握Ceph组件 3).搭建Ceph集群(了解) 2.Ceph使用 1).基于Ceph实现文件上传 2).基于Ceph实现文件下载 3.SKU、SPU管理 1).掌握SKU和SPU关系 2).理解商品发…...
六十九:基于openssl实战验证RSA
RSA(Rivest-Shamir-Adleman)是一种非对称加密算法,广泛应用于数据加密和数字签名领域。在实际开发和学习过程中,理解 RSA 的工作原理和使用场景非常重要。本文将以 OpenSSL 工具为基础,通过实例操作来验证和理解 RSA 的…...
Three.js 用户交互:构建沉浸式3D体验的关键
文章目录 前言一、基本交互:鼠标与触摸事件二、高级交互:键盘控制与游戏手柄支持三、物理模拟与碰撞检测四、手势识别与多点触控五、增强现实(AR)与虚拟现实(VR)六、触觉反馈与震动效果七、语音控制八、眼球…...
Android车机DIY开发之学习篇(五)默认应用修改
Android车机DIY开发之学习篇(五)默认应用修改 android默认应用位置 sdk/packages/apps InitRC配置 应用安装的目录 /system/priv-app 该路径存放一些系统底层的应用,比如Setting,systemUI等。该目录中的app拥有较高的系统权限,而且如果要使…...
linux 设置mysql 外网访问
1、修改 MySQL 配置文件 找到并编辑配置文件:在Linux系统中,MySQL的配置文件通常是/etc/mysql/my.cnf,使用命令sudo vim /etc/mysql/my.cnf打开文件。 注释或修改 bindaddress:找到bindaddress 127.0.0.1,将其注释掉…...
车企携手Tech Soft 3D:基于 HOOPS 工具集打造Web端一体化工程可视化解决方案
随着汽车行业向智能化、电动化转型,整车研发体系正在发生深刻变化。围绕多平台架构、跨区域协同以及供应链一体化,企业对于工程数据的使用方式提出了更高要求——不仅要“能管理”,更要“能流动、能协同”。 为推动核心工程系统向浏览器化、…...
HDSceneColor节点]原理解析与实际应用
渲染管线兼容性详解HD Scene Color节点的可用性完全取决于所使用的渲染管线,这是开发者在选择和使用该节点时必须首先考虑的因素。高清渲染管线(HDRP)支持HDRP是Unity针对高端平台和高端硬件设计的高保真渲染解决方案HD Scene Color节点专为H…...
Graphormer在计算毒理学中的应用:预测hERG通道抑制活性的完整建模流程
Graphormer在计算毒理学中的应用:预测hERG通道抑制活性的完整建模流程 1. 项目概述 Graphormer是一种基于纯Transformer架构的图神经网络,专门为分子图(原子-键结构)的全局结构建模与属性预测而设计。该模型在OGB、PCQM4M等分子…...
从原理到代码:深入解析UniFormer的多头关系聚合器(MHRA)设计
从原理到代码:深入解析UniFormer的多头关系聚合器(MHRA)设计 视频理解领域近年来经历了从3D卷积网络到视觉Transformer的范式转变,但两者在时空特征提取上各有限制。3D CNN擅长捕捉局部时空特征却受限于固定感受野,而视觉Transformer虽能建模…...
CasRel在智能问答系统中的落地实践:为QA引擎注入结构化事实支撑
CasRel在智能问答系统中的落地实践:为QA引擎注入结构化事实支撑 1. 引言:当问答系统遇到关系抽取 想象一下这样的场景:用户向智能问答系统提问"苹果公司的CEO是谁?",系统需要快速准确地回答"蒂姆库克…...
Phi-4-mini-reasoning部署教程:Nginx反向代理+Basic Auth安全加固
Phi-4-mini-reasoning部署教程:Nginx反向代理Basic Auth安全加固 1. 项目介绍 Phi-4-mini-reasoning是一款由微软开源的轻量级AI模型,专注于数学推理、逻辑推导和多步解题等强逻辑任务。这个3.8B参数的模型虽然体积小巧,但在推理能力上表现…...
别再手动调时间了!手把手教你用LinuxPTP的ptp4l和phc2sys搞定TSN网络时钟同步
工业TSN网络高精度时钟同步实战:从原理到生产环境部署 在工业自动化、智能驾驶和实时音视频传输领域,微秒级的时间同步已成为刚需。传统NTP协议毫秒级的精度在这些场景下显得力不从心,而基于IEEE 1588和802.1AS协议的PTP(精确时间…...
写段代码教会你什么是HOOK技术?HOOK技术能干什么?
起因是我想在搞一些操作windows进程的事情时,老是需要右键以管理员身份运行,感觉很麻烦。就研究了一下怎么提权,顺手瞄了一眼Windows下用户态权限分配,然后也是感谢《深入解析Windows操作系统》这本书给我偷令牌的灵感吧ÿ…...
番茄小说下载器:Rust构建的高性能离线阅读解决方案
番茄小说下载器:Rust构建的高性能离线阅读解决方案 【免费下载链接】Tomato-Novel-Downloader 番茄小说下载器不精简版 项目地址: https://gitcode.com/gh_mirrors/to/Tomato-Novel-Downloader 在数字阅读时代,网络依赖、格式不兼容和下载效率低下…...
本地Cookie管理工具:安全导出与高效应用指南
本地Cookie管理工具:安全导出与高效应用指南 【免费下载链接】Get-cookies.txt-LOCALLY Get cookies.txt, NEVER send information outside. 项目地址: https://gitcode.com/gh_mirrors/ge/Get-cookies.txt-LOCALLY 在当今数字化环境中,Cookie作为…...
