Qt——智能指针实战

目录

  • 前言
  • 正文
    • 一、理论介绍
      • 1、QPointer
      • 2、QScopedPoint
      • 3、QSharedPoint
      • 4、QWeakPoint
    • 二、实战演练
      • 1、QPoint
      • 2、QScopedPoint
      • 3、QSharedPoint
        • a、示例一
        • b、示例二
      • 4、QWeakPoint
    • END、总结的知识与问题
  • 参考

前言

智能指针的使用,对很多程序员来说,都算是比较高深的存在,但又老是感觉这是一个值得去掌握,且需要去掌握的东西,所以,这次下定决心,来掌握一下Qt的智能指针的使用,当然,最常用的肯定是QSharedPoint这个了,其他的应该也就是顺带着讲一讲,并且,普及一些知识,从而让自己的能力更上一层楼把。

正文

一、理论介绍

1、QPointer

QPointer是Qt提供的空安全的智能指针,它用于解决悬挂指针的问题。QPoint在对象被删除后,会自动被设置为nullptr,避免访问已经无效的对象,它类似于普通指针,但提供了一些安全检查。

总结来说就是:

当你创建一个对象,然后使用QPointer指向这个对象,若出现delete 了那个对象,但是未将那个对象置空的情况的话,判断的时候,直接判断QPointer对象,就可以知道到底是真的删除了那个对象,还是假的删除了。避免了悬挂指针的问题。

QPoint 充当一个管家的角色,对真正的指针做好判断。

2、QScopedPoint

QScopedPoint 是Qt提供的独占式的智能指针,用于管理动态分配的对象,QScopedPoint 在超出作用域时,自动删除对象,确保对象在不再需要时,被正确释放。

3、QSharedPoint

QSharedPoint 是Qt提供的共享引用计数的指针,可用于管理动态分配的对象。它通过引用计数跟踪对象的引用次数,当引用次数归零时,会自动删除对象。可以通过多个QSharedPoint共享同一个对象,对象会在最后一个引用者释放它时,才会被删除。

4、QWeakPoint

QWeakPoint 是Qt提供的弱引用智能指针,用于解决循环引用的问题。QWeakPoint 可以引用由QSharedPoint管理的对象,但不会增加引用计数的次数。QWeakPoint需要转换成QSharedPoint才能访问对象,当引用计数为0时,访问会失败。

二、实战演练

1、QPoint

MyClass.h

#ifndef MYCLASS_H
#define MYCLASS_H
#include <QPointer>
#include <QDebug>
class MyClass : public QObject
{Q_OBJECTpublic:MyClass(const QString& name): m_name(name){qDebug() << "MyClass 构造函数,名称为:"<<m_name;}~MyClass(){qDebug() << "MyClass 析构函数,名称为:"<<m_name;}QString getName() const {return m_name;}private:QString m_name;
};#endif // MYCLASS_H

main.cpp

#include <QCoreApplication>
#include <QPointer>
#include <QDebug>
#include "MyClass.h"int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);MyClass *obj = new MyClass("test");QPointer<MyClass> myObject(obj);if (myObject){qDebug() << "对象存在,名称为" << myObject->getName();}else{qDebug() << "对象不存在";}delete obj;if (myObject){qDebug() << "对象存在,名称为" << myObject->getName();}else{qDebug() << "对象不存在";}return a.exec();
}

2、QScopedPoint

void MainWindow::TestQScopedPointer()
{useResource();qDebug() << "useResource 函数执行完毕";
}void MainWindow::useResource()
{QScopedPointer<Resource> scopedResource(new Resource());;//执行一些操作,使用资源qDebug() << "---> 使用资源 ";
}

QScopedPoint 在适当的时候,会自动调用析构函数释放资源。

结果:

Resource 构造函数
---> 使用资源 
Resource 析构函数
useResource 函数执行完毕

3、QSharedPoint

a、示例一
#include <QSharedPointer>
#include <QScopedPointer>
#include <QDebug>
// 假设的图形对象类
class GraphicObject {
public:GraphicObject() { qDebug() << "GraphicObject created"; }~GraphicObject() { qDebug() << "GraphicObject destroyed"; }// 具体的图形对象操作
};
// 文档对象类
class Document {
public:Document() { qDebug() << "Document created"; }~Document() { qDebug() << "Document destroyed"; }// 添加图形对象到文档void addGraphicObject(QSharedPointer<GraphicObject> graphicObject) {graphicObjects.append(graphicObject);}// 具体的文档操作
private:QList<QSharedPointer<GraphicObject>> graphicObjects;
};
int main() {// 使用 QSharedPointer 确保图形对象的自动释放QSharedPointer<GraphicObject> graphicObject(new GraphicObject);// 使用 QScopedPointer 确保文档对象的自动释放QScopedPointer<Document> document(new Document);// 将图形对象添加到文档document->addGraphicObject(graphicObject);// 注意:在这里,graphicObject 和 document 会在适当的时候自动释放return 0;
}
b、示例二
#ifndef MYSHAREDCLASS_H
#define MYSHAREDCLASS_H
#include <QPointer>
#include <QDebug>
class MySharedClass : public QObject
{Q_OBJECTpublic:MySharedClass(int value): m_iValue(value){qDebug() << "MySharedClass 构造函数,值为:"<<m_iValue;}~MySharedClass(){qDebug() << "MySharedClass 析构函数,值为:"<<m_iValue;}void setValue(int value){m_iValue = value;}int getValue() const{return m_iValue;}private:QString m_name;int m_iValue;
};
#endif // MYSHAREDCLASS_H
void MainWindow::TestSharedPointer()
{//先用一个智能指针指向一个对象QSharedPointer<MySharedClass> pointer1(new MySharedClass(10));{//通过复制构造函数 让引用+1QSharedPointer<MySharedClass> pointer2 = pointer1;qDebug() << "---> pointer1 的值:"<<pointer1->getValue();qDebug() << "---> pointer2 的值"<<pointer2->getValue();//实际上都是对同一个对象进行操作pointer2->setValue(20);qDebug() << "--->w pointer1 的值:"<<pointer1->getValue();qDebug() << "--->w pointer2 的值"<<pointer2->getValue();}qDebug() << "--->w pointer1 的值:"<<pointer1->getValue();//之后,智能指针超出作用域之后,会自动析构掉
}

4、QWeakPoint

#ifndef MYWEAKCLASS_H
#define MYWEAKCLASS_H#include <QSharedPointer>
#include <QWeakPointer>
#include <QDebug>class ObjectB;class ObjectA
{
public:ObjectA(const QString& name) : m_name(name){}~ObjectA(){qDebug() << "objectA 析构函数,名称为:"<<m_name;}void setObjectB(const QSharedPointer<ObjectB> &objectB){m_objectB = objectB;}
private:QString m_name;QWeakPointer<ObjectB> m_objectB;
};class ObjectB
{
public:ObjectB(const QString& name): m_name(name){}~ObjectB(){qDebug() << "Object 析构函数,名称为:"<<m_name;}void setObjectA(const QSharedPointer<ObjectA> &objectA){m_objectA = objectA;}private:QString m_name;QSharedPointer<ObjectA> m_objectA;
};#endif // MYWEAKCLASS_H
void MainWindow::TestWeakPointer()
{QSharedPointer<ObjectA> objectA(new ObjectA("ObjectA"));QSharedPointer<ObjectB> objectB(new ObjectB("ObjectB"));objectA->setObjectB(objectB);objectB->setObjectA(objectA);qDebug() << "程序结束";
}

END、总结的知识与问题

参考

1、[Qt杂谈8.浅谈Qt智能指针那些事](https://www.cnblogs.com/luoxiang/p/17927569.html)

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

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

相关文章

发布文章积分自动增加

controller ApiOperation(value "添加文章")PostMapping("/addwengzhang")public String addwengzhang(RequestBody WengDto wengDto) {if (wengDto.getContent() null || wengDto.getTitle() null) {return "参数不可为空";}User user user…

【MySQL】InnoDB引擎

逻辑结构 InnoDB存储引擎逻辑结构如图所示&#xff1a; Tablespace&#xff1a;表空间&#xff0c;一个数据库可以对应多个表空间。数据库中的每张表都有一个表空间&#xff0c;用来存放表记录、索引等数据。 Segment&#xff1a;段&#xff0c;表空间中有多个段&#xff0c…

第九届蓝桥杯大赛个人赛省赛(软件类)真题C 语言 A 组-乘积尾零

solution 找末尾0的个数&#xff0c;即找有多少对2和5 >问题等价于寻找所给数据中&#xff0c;有多少个2和5的因子&#xff0c;较少出现的因子次数即为0的个数 #include <iostream> using namespace std; int main() {// 请在此输入您的代码printf("31");…

Java代码基础算法练习-搬砖问题-2024.03.25

任务描述&#xff1a; m块砖&#xff0c;n人搬&#xff0c;男搬4&#xff0c;女搬3&#xff0c;两个小孩抬一砖&#xff0c;要求一次全搬完&#xff0c;问男、 女、小孩各若干&#xff1f; 任务要求&#xff1a; 代码示例&#xff1a; package M0317_0331;import java.util.S…

3.C++:类与对象(下)

一、再谈构造函数 1.1构造函数体赋值 在创建对象时&#xff0c;编译器通过调用构造函数&#xff0c;给对象中各个成员变量一个合适的初始值。 class Date { public:Date(int year, int month, int day){_year year;_month month;_day day;}private:int _year;int _month;i…

== 和 equals 的区别是什么?

和 equals() 在 Java 中都是用于比较两个对象&#xff0c;但它们之间存在显著的差异&#xff1a; 比较的内容&#xff1a; &#xff1a;这是 Java 中的基本比较运算符&#xff0c;对于基本数据类型&#xff08;如 int, char, double 等&#xff09;&#xff0c;它比较的是值&a…

二手车交易网站|基于JSP技术+ Mysql+Java+ B/S结构的二手车交易网站设计与实现(可运行源码+数据库+设计文档)

推荐阅读100套最新项目 最新ssmjava项目文档视频演示可运行源码分享 最新jspjava项目文档视频演示可运行源码分享 最新Spring Boot项目文档视频演示可运行源码分享 2024年56套包含java&#xff0c;ssm&#xff0c;springboot的平台设计与实现项目系统开发资源&#xff08;可…

将若依项目部署上线

1. 购买轻量服务器&#xff0c;新人优惠一年61元&#xff08;有点赚&#xff09;&#xff1b; 2. 在轻量服务器重置密码&#xff0c;再远程连接。 3. 登录宝塔面板&#xff1b; 4. 下载mysql5.7&#xff0c;redis7.2&#xff0c;nginx 5. 在宝塔页面设置数据库密码&#xf…

快速熟悉ElasticSearch的基本概念

1.全文检索 全文检索是通过文本内容进行全面搜索的技术。通过全文检索可以快速地在大量文本数据中查找包含特定关键词或者短语的文档&#xff0c;并且返回相关的搜索结果。 检索和查询的区别 检索没有搜索条件边界&#xff0c;检索的结果取决于相关性&#xff0c;相关性计算…

VUE:内置组件<Teleport>妙用

一、<Teleport>简介 <Teleport>能将其插槽内容渲染到 DOM 中的另一个位置。也就是移动这个dom。 我们可以这么使用它: 将class为boxB的盒子移动到class为boxA的容器中。 <Teleport to".boxA"><div class"boxB"></div> &…

OC高级编程 第3章:Grand Central Dispatch

3.1 Grand Central Dispatch (GCD)概要 3.1.1什么是GCD Grand Central Dispatch&#xff08;GCD&#xff09;是异步执行任务的技术之一。一般将应用中记述线程管理用的代码在系统级中实现。开发者只要定义想执行的任务并追加到Dispatch Queue中&#xff0c;GCD就能生成必要的…

如何使用Docker安装Paperless-ngx系统并实现远程在线搜索查阅文档

文章目录 1. 部署Paperless-ngx2. 本地访问Paperless-ngx3. Linux安装Cpolar4. 配置公网地址5. 远程访问6. 固定Cpolar公网地址7. 固定地址访问 Paperless-ngx是一个开源的文档管理系统&#xff0c;可以将物理文档转换成可搜索的在线档案&#xff0c;从而减少纸张的使用。它内置…

登录注册界面

T1、编程设计理工超市功能菜单并完成注册和登录功能的实现。 显示完菜单后&#xff0c;提示用户输入菜单项序号。当用户输入<注册>和<登录>菜单序号时模拟完成注册和登录功能&#xff0c;最后提示注册/登录成功并显示注册信息/欢迎XXX登录。当用户输入其他菜…

Docker操作基础命令

注意&#xff1a;以下命令在特权模式下进行会更有效&#xff01; 进入特权模式 sudo -ssudo su拉取镜像 sudo docker pull [镜像名] # sudo docker pull baiduxlab/sgx-rust:2004-1.1.3进入容器 端口开启服务&#xff1a; sudo docker start 3df9bf5dbd0c进入容器&#xf…

Open CASCADE学习|将圆转换为NURBS曲线

NURBS曲线&#xff0c;全称非均匀有理B样条曲线&#xff08;Non-Uniform Rational B-Splines&#xff09;&#xff0c;是计算机图形学中用于表示几何形状的数学表示方法。它结合了非均匀B样条&#xff08;B-Splines&#xff09;和有理基函数&#xff08;Rational Basis Functio…

R语言迅速计算多基因评分(PRS)

Polygenic Risk Scores in R 最朴素的理解PRS&#xff1a; GWAS分析结果中&#xff0c;有每个SNP的beta值、se值、P值&#xff0c;因为GWAS分析中将SNP变为0-1-2编码&#xff0c;所以这些显著的SNP的beta值&#xff0c;就可以用于预测。 比如&#xff1a;GWAS分析中&#xf…

SQL语言: 基本操作

DDL(数据定义) 库 创建数据库 CREATE DATABASE database_name; 删除数据库 DROP DATABASE database_name; 选择数据库 USE database_name; 表 创建表格 CREATE TABLE table_name( column1 datatype, column2 datatype, ... ); 删除表格 DROP TABLE table_name; 修改表格ALT…

linux内核网络中的互斥 “每日读书”

网络代码中广泛使用上锁&#xff0c;本书中每项主题下&#xff0c;可能都会发现上锁的议题&#xff0c;对众多程序设计类型而言&#xff0c;尤其是针对内核的程序设计&#xff0c;互斥&#xff0c;上锁机制以及同步都是一般性主题&#xff0c;而且相当有趣复杂&#xff0c;linu…

QT_day3:2024/3/22

作业1&#xff1a;设计界面 使用手动连接&#xff0c;将登录框中的取消按钮使用qt4版本的连接到自定义的槽函数中&#xff0c;在自定义的槽函数中调用关闭函数 将登录按钮使用qt5版本的连接到自定义的槽函数中&#xff0c;在槽函数中判断ui界面上输入的账号是否为"admin…

【Java基础知识总结 | 第六篇】Java反射知识总结

文章目录 6.Java反射知识总结6.1概述6.1.1什么是反射&#xff1f;6.1.2为什么使用反射&#xff1f; 6.2反射的原理6.3反射的使用6.3.1获取类对象&#xff08;1&#xff09;通过具体类的类名获取&#xff08;2&#xff09;通过对象实例获取&#xff08;3&#xff09;通过class.f…