QT对象树 | 内存泄漏

news2024/11/18 17:46:33

使用 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.coloradmin.cn/o/1492233.html

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

相关文章

外包干了3个月,技术倒退明显

先说情况&#xff0c;大专毕业&#xff0c;18年通过校招进入湖南某软件公司&#xff0c;干了接近6年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试&#xf…

主备DNS服务器搭建并验证

目录 1. 配置静态网络 2. 配置主备DNS 2.1 DNS备服务器&#xff08;第二个虚拟机&#xff09; 2.2 两个虚拟机操作 2.3 备用服务器&#xff08;第二个虚拟机&#xff09;执行 2.4 两个虚拟机都添加DNS: 3. 验证 3.1 主DNS服务验证: 3.2 备用DNS服务器验证&am…

基于Springboot的足球俱乐部管理系统(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的足球俱乐部管理系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot项目。 项目介绍: 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&#xff…

C语言指针的初步认识--学习笔记(3)

1. 字符指针变量 在C语言中&#xff0c;字符串通常被视为字符数组&#xff0c;但它们可以有不同的表示方式。字符指针变量存储的是字符串的地址。这意味着&#xff0c;当你有一个字符串时&#xff0c;你可以通过改变字符指针的值来改变这个字符串&#xff0c;因为你实际上改变的…

22.欧拉方法、刚体模拟、流体模拟

一、一个粒子的模拟 规定一个物体在某一个时刻的速度和位置&#xff0c;如何解出某个时间之后它会出现在哪里 下图要求模拟一个粒子在速度场中要如何运动 速度场中&#xff0c;在任何一个位置&#xff0c;我们都有它的速度 写出来相当于是常微分方程 我们知道速度&#xff0c;…

find函数-秒了道题

秒了 笑死 还是规规矩矩做吧 string类的find()函数用于在字符串中查找字符或子串&#xff0c;返回第一个匹配的位置。 class Solution { public:int strStr(string haystack, string needle) {return haystack.find(needle);} };

基于灰狼算法GWO的城市三维无人机路径规划(复杂地形三维航迹路径规划)

摘要 本文提出了一种利用灰狼算法GWO来解决城市环境下无人机三维路径规划问题的方法。这种方法将复杂的无人机航迹规划任务转化为一个优化问题&#xff0c;然后运用灰狼算法GWO来解决这个优化问题。灰狼算法GWO是一种模拟灰狼种群捕猎行为的优化算法&#xff0c;它具备强大的全…

【TEE】内存完整性保护

Hash Functions&Merkle Tree 对读操作进行完整性检查&#xff0c;通过在加载的块上重新计算一个哈希&#xff0c;然后根据片外地址将得到的哈希与片上哈希比较。 缺点&#xff1a;不可承受的片上存储开销&#xff0c;并假设128位哈希和512位cache line&#xff0c;其开销为…

C++基于多设计模式下的同步异步日志系统day6

C基于多设计模式下的同步&异步日志系统day6 &#x1f4df;作者主页&#xff1a;慢热的陕西人 &#x1f334;专栏链接&#xff1a;C基于多设计模式下的同步&异步日志系统 &#x1f4e3;欢迎各位大佬&#x1f44d;点赞&#x1f525;关注&#x1f693;收藏&#xff0c;&am…

JPA generator 生成实体类

1、配置生成实体类 选中表后点击右键 2、 Generate POJOs.groovy 配置 import com.intellij.database.model.DasTable import com.intellij.database.model.ObjectKind import com.intellij.database.util.Case import com.intellij.database.util.DasUtilimport java.text.S…

K次取反后最大化的数组和 加油站 分发糖果 柠檬水找零

1005.K次取反后最大化的数组和 力扣题目链接(opens new window) 给定一个整数数组 A&#xff0c;我们只能用以下方法修改该数组&#xff1a;我们选择某个索引 i 并将 A[i] 替换为 -A[i]&#xff0c;然后总共重复这个过程 K 次。&#xff08;我们可以多次选择同一个索引 i。&a…

类与对象(二)--类的六个默认成员函数超详细讲解

目录 1.类的默认六个成员函数✒️ 2.构造函数 2.1构造函数的概念✒️ 2.2构造函数的特性✒️ 3.析构函数 3.1析构函数的概念✒️ 3.2析构函数的特征✒️ 4.拷贝构造函数 4.1拷贝构造函数的概念✒️ 4.2拷贝构造函数的特征✒️ 4.3思考❓ 4.4深拷贝和浅拷贝⭐️…

嵊州吃喝玩乐篇

1. 豆腐馒头 胖大姐豆腐馒头&#xff08;推荐&#xff09; 地址: 嵊州市越秀路96-98号 高德地图搜 “胖大姐黄泽豆腐馒头” 黄泽豆腐馒头 地址&#xff1a;嵊州市越秀路111号 高德地图搜 “嵊州市玉英豆腐馒头店” 2. 烧烤 老张烧烤&#xff08;推荐&#xff09; 地址&a…

3.5作业

1.使用write 和 read 实现 文件夹拷贝功能&#xff0c;不考虑递归拷贝 #include<stdio.h> #include<string.h> #include<unistd.h> #include<stdlib.h> #include<sys/types.h> #include<sys/stat.h> #include<fcntl.h> int main(in…

#stm32学习总结GPIO

1、 GPIO 1.1、简介 就是通用输入输出口 2&#xff0c; STM32 GPIO简介&#xff08;了解&#xff09; 2.1&#xff0c;GPIO特点 1&#xff0c;不同型号&#xff0c;IO口数量可能不一样&#xff0c;可通过选型手册快速查询 2&#xff0c;快速翻转&#xff0c;每次翻转最快只…

PTA L2-009 抢红包

题目&#xff1a; 没有人没抢过红包吧…… 这里给出N个人之间互相发红包、抢红包的记录&#xff0c;请你统计一下他们抢红包的收获。 输入格式&#xff1a; 输入第一行给出一个正整数N&#xff08;≤104&#xff09;&#xff0c;即参与发红包和抢红包的总人数&#xff0c;则…

【网站项目】121开放式教学评价管理系统

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

EtherCAT运动控制器在ROS上的应用(上)

本文以正运动技术EtherCAT运动控制器ZMC432和ZMC408CE为例&#xff0c;介绍正运动技术运动控制器在ROS上的应用开发。 在正式学习之前&#xff0c;我们先了解一下正运动技术的EtherCAT运动控制器ZMC432和ZMC408CE。这两款产品分别是32轴&#xff0c;8轴EtherCAT运动控制器。 …

分享Web.dev.cn中国开发者可以正常访问

谷歌开发者很高兴地宣布&#xff0c;web.dev 和 Chrome for Developers 现在都可以通过 .cn 域名访问&#xff0c;这将帮助中国的开发者更加容易获取我们的内容。 在 .cn 域名上&#xff0c;我们已向您提供所有镜像后的内容&#xff0c;并提供支持的语言版本。 Web.dev 中国开…

【Unity】使用ScriptableObject存储数据

1.为什么要用ScriptableObject&#xff1f; 在游戏开发中&#xff0c;有大量的配置数据需要存储&#xff0c;这个时候就需要ScriptableObject来存储数据了。 很多人会说我可以用json、xml、txt&#xff0c;excel等等 但是你们有没有想过&#xff0c;假设你使用的是json&#x…