QT对象树 | 内存泄漏

使用 Qt 框架构建 GUI 界面的程序

//widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QLabel>Widget::Widget(QWidget *parent)  //这里的parent的意思是父级指针: QWidget(parent)  //调用父类的构造函数, ui(new Ui::Widget)  
{ui->setupUi(this);QLabel* lable = new QLabel(this);  //在堆上创建一个QLabel对象lable->setText("hello world");  //调用对象的显示方法
}Widget::~Widget()
{delete ui;
}

在这里插入图片描述


对象树

提示:这里可以添加要学的内容

在qt中创建对象的时候会提供一个Parent对象指针,下面来解释这个Parent指针是干什么的:

(1)QObject是以对象树的形式组织起来的

在这里插入图片描述

当创建一个对象QObject对象时,会看到QObject的构造函数接收一个QObject指针为参数,这个参数就是Parent,也就是父对象指针。这相当于,在创建QObject对象时,可以提供一个其父对象(指定父亲),我们创建的这个QObject对象会自动添加到其父对象的children()列表

(2)当父对象析构的时候,其父对象的children()列表中的所有对象也会被析构(注意这里的父对象并不是继承意义上的父类)。形象化的解释就是当释放窗口时,窗口内的组件对象也会被释放,这是合理的

(3)因此可以在代码中肆意创建对象,只要指定父对象,父对象包含管理释放(析构),那么子对象在父对象析构的时候会自动析构

(4) 对象树中,析构的顺序和构造的顺序是相反的

代码感受对象树
在这里插入图片描述
我们自己先创建一个ObjectTree文件,在这个文件里面添加一个C++的MyLabel类

因为我们要使用QLabel类,需要将自己的MyLabel类继承QLabel,自己写构造函数和析构函数
在这里插入图片描述

MyLabel完善之后,我们就可以在widget.cpp里面编写代码了
在这里插入图片描述
QWidget是widget的父亲,MyLabel是widget的儿子,这样析构widget对象的时候会自动析构MyLabel对象
在这里插入图片描述
当我们关闭这个窗体的时候,会看见自己定义的MyLabel类的析构被调用在这里插入图片描述

对象树:这个概念非常好理解。因为 QObject 类就有一个私有变量 QList<QObject *>,专门存储这个类的子孙后代们。比如创建一个 QObject 并指定父对象时,就会把自己加入到父对象的 children() 列表中,也就是 QList<QObject *> 变量中。


使用对象树模式有什么好处?

提示:这里可以添加计划学习的时间

好处就是:当父对象被析构时子对象也会被析构。从一定程度上讲,简化了内存回收机制。

举个例子,有一个窗口 Window,里面有 Label标签、TextEdit文本输入框、Button按钮这三个元素,并且都设置 Window 为它们的父对象。这时候我做了一个关闭窗口的操作,作为程序员的你是不是自然想到将所有和窗口相关的对象析构啊?古老的办法就是一个个手动 delete 呗。是不是很麻烦?Qt 运用对象树模式,当父对象被析构时,子对象自动就 delete 掉了,不用再写一大堆的代码了。

所以,在我点击该运行程序的X后,系统会根据这个树状的结构,释放掉整个结构的内存。


对象树的问题(代码示例)

#include "widget.h"#include <QApplication>
#include<QLabel>
#include<QPushButton>int main(int argc, char *argv[])
{QApplication a(argc, argv);QPushButton button;Widget w;button.setParent(&w);button.setText("QT崩溃");w.show();return a.exec();
}

在这里插入图片描述

在本例中,button和w按照顺序存放在栈里,而我们栈有先进后出的特性,正因如此,我们的程序结束后,系统会先释放w的内存,再释放button的内存,在释放w的内存时候由于 button变量绑定了父变量w(button.setParent(&w)😉,button也会和w一起释放,因此button在本例中会进行两次释放,从而导致奔溃

中创建对象的时候会提供一个 Parent对象指针(可以查看类的构造函数),下面来解释这个 parent 到底是干什么的。

QObject 是以对象树的形式组织起来的。当你创建一个QObject对象时,会看到QObject的构造函数接收一个QObject指针作为参数,这个参数就是 parent,也就是父对象指针。这相当于,在创建 QObject 对象时,可以提供一个其父对象,我们创建的这个 QObject 对象会自动添加到其父对象的 children () 列表。当父对象析构的时候,这个列表中的所有对象也会被析构。(注意,这里的父对象并不是继承意义上的父类!)

QWidget 是能够在屏幕上显示的一切组件的父类。QWidget 继承自 QObject,因此也继承了这种对象树关系。一个孩子自动地成为父组件的一个子组件。因此,它会显示在父组件的坐标系统中,被父组件的边界剪裁。例如,当用户关闭一个对话框的时候,应用程序将其删除,那么,我们希望属于这个对话框的按钮、图标等应该一起被删除。事实就是如此,因为这些都是对话框的子组件。

Qt 引入对象树的概念,在一定程度上解决了内存问题。

(1)当一个 QObject 对象在堆上创建的时候,Qt 会同时为其创建一个对象树。不过,对象树中对象的顺序是没有定义的。这意味着,销毁这些对象的顺序也是未定义的。

(2)任何对象树中的 QObject 对象 delete 的时候,如果这个对象有 parent,则自动将其从 parent 的 children () 列表中删除;如果有孩子,则自动 delete 每一个孩子。Qt 保证没有 QObject 会被 delete 两次,这是由析构顺序决定的。

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

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

相关文章

智慧城市中的数字孪生:数字孪生技术助力智慧城市提高公共服务水平

目录 一、引言 二、数字孪生技术概述 三、数字孪生技术在智慧城市中的应用 1、智慧交通管理 2、智慧能源管理 3、智慧环保管理 4、智慧公共安全 四、数字孪生技术助力智慧城市提高公共服务水平的价值 五、挑战与前景 六、结论 一、引言 随着信息技术的飞速发展&…

成功交付 | 精益DevOps

⭐简单说两句⭐ 作者&#xff1a;后端小知识&#xff0c;CSDN后端领域新星创作者|阿里云专家博主 CSDN个人主页&#xff1a;后端小知识 &#x1f50e;GZH&#xff1a;后端小知识 &#x1f389;欢迎关注&#x1f50e;点赞&#x1f44d;收藏⭐️留言&#x1f4dd; 按需交付服务从…

python网络爬虫教程笔记(1)

系列文章目录 文章目录 系列文章目录前言一、爬虫入门1.爬虫是什么&#xff1f;2.爬虫工作原理3.爬虫基本原理4.工作流程5.HTTP请求6.HTTP响应7.HTTP原理&#xff1a;证书传递、验证和数据加密、解密过程解析8.Urllib.request库的使用9.TCP3次握手&#xff0c;4次挥手过程 总结…

Express学习(一)

Express Express简介 什么是Express 官方给出的概念&#xff1a;Express是基于Node.js平台&#xff0c;快速、开放、极简的web开发框架。 通俗的理解&#xff1a;Express的作用和Node.js内置的http模块类似&#xff0c;是专门用来创建Web服务器的。进一步理解Express 不使用E…

ssm+springboot音乐播放器网站mybatis+jsp

测试流程 &#xff08;1&#xff09; 登录系统、填写用户名、密码选择角色&#xff0c;主要内容&#xff1a;进行权限控制。 &#xff08;2&#xff09; 用户查看音乐信息、音乐资讯功能&#xff0c;主要是测试系统实用性、方便性。 &#xff08;3&#xff09; 信息修…

云桥通+跨国游戏:SDWAN组网解析跨国游戏企业的成功案例

运气通曾服务过一家国际知名的游戏开发公司C&#xff0c;C公司的游戏广受年轻人欢迎&#xff0c;所以&#xff0c;他C公司也顺理成章地拥有全国玩家基础。由于游戏的在线特性和全球用户分布&#xff0c;C公司面临着跨国游戏服务器之间的苦恼——稳定问题和网络连接问题。他们希…

有个朋友被骗了,大家要擦亮眼睛

1.引言 大家好&#xff0c;我是Leo哥&#x1fae3;&#x1fae3;&#x1fae3;&#xff0c;昨天凌晨有个粉丝朋友找到Leo哥&#xff0c;咨询一些问题&#xff0c;现在的朋友们真卷呐&#xff0c;大半夜还在挑灯夜战。可无奈Leo哥12点之前已经睡了&#xff0c;身体为重&#xf…

python水表识别图像识别深度学习 CNN

python水表识别&#xff0c;图像识别深度学习 CNN&#xff0c;Opencv,Keras 重点&#xff1a;项目和文档是本人近期原创所作&#xff01;程序可以将水表图片里面的数据进行深度学习&#xff0c;提取相关信息训练&#xff0c;lw1.3万字重复15%&#xff0c;可以直接上交那种&…

kafka查看消息两种方式(命令行和软件)+另附发送消息方式

1、命令行方式 ①找到kafka安装文件夹 ②执行命令 #指定offset为指定时间作为消息起始位置 kafka-consumer-groups.sh \ --bootstrap-server 20.2.246.116:9092 \ --group group_1 \ --topic lanxin_qiao \ --reset-offsets \ --to-datetime 2023-07-19T01:00:00.000 \ -exe…

HTML简介:想成为前端开发者?先从掌握HTML开始!

在这个数字化的时代&#xff0c;我们每天都在与网页打交道。你是否曾经好奇过&#xff0c;这些充满魔力的网页是如何诞生的呢&#xff1f;今天&#xff0c;我们就来揭开构成这些网页的神秘面纱——HTML&#xff08;超文本标记语言&#xff09;。 一、什么是HTML 网页的基本组…

Qt绘制动态罗盘

介绍&#xff1a;罗盘指针以30角旋转巡逻&#xff0c;扫描航海范围内的点位&#xff0c;并绘制点云。字段信息在表格中显示&#xff0c;该数据都存储在数据库中。选择不同的范围&#xff0c;显示该范围内的点位。 #include "mainwindow.h" #include "ui_mainwi…

【QT】窗口的大小标题图标设置

窗口的大小标题图标设置 添加一个新的类 创建完成&#xff0c;根据上一节最后的在总结&#xff0c;做个测试&#xff1a; #include "mybutton.h" #include <QDebug>//打印&#xff0c;标准输出 MyButton::MyButton(QWidget *parent) : QPushButton(parent) { …