Qt中对象树机制的优点以及潜在的隐患

目录

一、什么是对象树

二、对象树的优点

三、对象树潜在的隐患


一、什么是对象树

        Qt中的 QObject 会用对象树来组织管理自己,那什么是对象树?

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

        注意:这个父子关系不是指类中继承的父子关系,这一点需要重点强调以下。QT里面的这个父子关系和类中的语法没有半毛钱的关系。

        举个例子:就是一个我们讲一个对话框Dialog,其中有一个button按钮,它属于对话框的一个组成部分。那我们就把这个按钮称为它的一个子对象。这样的一个对话框呢,就叫做这个子对象的父对象,其中实际的操作就是按钮设置parent为对话框Dialog,对话框就是作为button的父对象。

二、对象树的优点

        好处就是:当父对象被析构时子对象也会被析构。

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

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

三、对象树潜在的隐患

        任何事物都有两面性,Qt中的对象树机制也是一样,它有好处当然也会存在相应的隐患。

 隐患就是:会导致双重释放。

        那是什么意思呢,就是说,在Qt中,如果一个QObject对象同时被其对象树和程序中的其他部分(如栈或堆上的直接管理)所持有,那么当对象树被销毁时,该对象可能会被自动删除。如果之后程序中的其他部分又尝试删除该对象,就会导致双重释放,进而可能引发程序崩溃。 

举一个例子:

        看下面一段代码,在 main.cpp 文件中创造一个QPushButton类,同时创造了一个Widget窗口,btn 指定 w 父对象。

        如果不仔细查看,代码没有什么问题。但其实程序已经出现崩溃。原因是:在main 函数中,变量存储在栈中,栈的特点为 后进先出,也就是说,w 先出栈,btn后出栈。由于对象树的机制,btn 指定 w 作为  父对象,它会在 w 析构之前被析构一次,而 w 出栈又被析构一次,这就导致了双重释放,程序会崩溃。

        崩溃结果为:

        同时正确写法应该为:创建 btn 应该在 w 的后面,也就会先释放btn,后释放 w,因为这样对象树内部同样还有一个机制,如果它查询到了 btn 已经被释放了,那么它就不会再继续释放 btn 内存了。 

        

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

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

相关文章

centos7-8/redhat7-8一键安装配置vsftp服务

1.脚本介绍 1.1.介绍&#xff1a; linux下一键安装及配置vsftpd服务 &#xff0c;通过执行install.sh脚本&#xff0c;脚本会根据参数区域的值执行安装和配置vsftp服务&#xff0c;安装后会创建一个默认ftp用户wangxf密码wangxf2023 1、支持自定义安装(更改脚本内参数值) 2、…

一篇文章带你入门爬虫并编写自己的第一个爬虫程序

一、引言 目前我们处在一个信息快速迭代更新的时代&#xff0c;海量的数据以大爆炸的形式出现在网络之中&#xff0c;相比起过去那个通过广播无线电、书籍报刊等传统媒介获取信息的方式&#xff0c;我们现在通过网络使用搜索引擎几乎可以获得任何我们需要的信息资源。 但与此同…

优化mac outlook通过nginx反向代理后使用ews访问Exchange 2016邮件访问速度慢的有效方法

在nginx配置exchange的反向代理后,mac系统上通过exchange邮箱,通过nginx代理连接邮箱,发现速度很慢,通过查看日志,也存在大量的401失败日志。通过不断的优化和尝试,目前来看,基本上正常了,基本上没有出现大量访问失败的问题。以下就是优化过程中尝试过的方法。 1. 身份…

【精通Redis】Redis命令详解

引言 Redis是一个内存数据库&#xff0c;在学习它的内部原理与实现之前&#xff0c;我们首先要做到的就是学会使用&#xff0c;学会其丰富的命令操作。 一、字符串 Redis的字符串类型之前笔者的一篇入门介绍中曾经说过&#xff0c;不是简单的只存人可以阅读的字符串&#xf…

【前端 19】使用Vue-CLI脚手架构建Vue2项目

使用Vue CLI构建Vue 2项目 引言 Vue.js 是一个构建用户界面的渐进式JavaScript框架&#xff0c;以其轻量级和易用性受到前端开发者的广泛喜爱。Vue CLI&#xff08;Vue Command Line Interface&#xff09;是一个基于Vue.js进行快速开发的完整系统&#xff0c;提供了零配置的项…

数据结构之线性表(顺序表的实现)

目录 一、线性表的原理 二、线性表的实现&#xff08;顺序表&#xff09; 1.定义顺序表 2.初始化顺序表 3.判断顺序表是否为空 4.获取顺序表的长度 5.向顺序表中插入元素 6.删除指定位置的元素 7.遍历顺序表 8.得到指定位置的元素 三、打印测试功能 1.测试 2.结果…

全球相机控制面板市场展望与未来增长机遇:预计未来六年年复合增长率CAGR为4.3%

在全球摄影器材和专业影像设备需求增长的背景下&#xff0c;相机控制面板正成为市场的焦点。本文详细分析了全球相机控制面板市场的现状、增长趋势及未来前景&#xff0c;旨在为投资者和业内人士提供深入的市场洞察和指导。 市场概览 据恒州诚思团队研究分析显示&#xff0c;2…

RK3568笔记四十七:PWM 子系统

若该文为原创文章&#xff0c;转载请注明原文出处。 pwm 子系统功能单一&#xff0c;很少单独使用&#xff0c;一般用于控制显示屏的背光、控制无源蜂鸣器、伺服电机、电压调节等等。 一、PWM介绍 PWM(Pulse width modulation)&#xff0c;脉冲宽度调制。在内核中 PWM 驱动较简…

学习大数据DAY26 简单数据清洗练习和 Shell 脚本中的数据库编程

目录 上机练习 14 mysql 命令 sql 语句实现步骤 shell 脚本导入 csv 格式文件到 mysql 数据库 secure-file-priv 特性 把文件拷贝到 mysql 指定目录下 上机练习 15 mysqldump 命令 上机练习 16 上机练习 14 运用上一节课学的 Shell 工具完成 1. 清洗数据《infotest.t…

CentOS7 yum报错Cannot find a valid baseurl for repo

问题 Loaded plugins: fastestmirror Determining fastest mirrors Could not retrieve mirrorlist http://mirrorlist.centos.org/?release7&archx86_64&repoos&infravag error was 14: curl#6 - "Could not resolve host: mirrorlist.centos.org; Unknown…

前端canvas——五子棋小游戏开发

这估计是最后一篇了&#xff0c;终于是修复了部分bug——隔一个空格能够胜利的bug&#xff0c;并且添加了部分样式。 其他bug目前还没有找到&#xff0c;找到再说吧。 大部分代码请见&#xff1a; 用canvas实现五子棋小游戏https://blog.csdn.net/m0_54066656/article/detail…

后端笔记(2)--JDBC

1.JDBC简介 *JDBC(Java DataBase Connectivity)就是使用java语言操作关系型数据库的一套API *JDBC本质&#xff1a;&#xff08;可以使用同一套代码&#xff0c;操作不同的关系型数据库&#xff09; ​ *官方定义的一套操作所有关系型数据库的规则&#xff0c;即接口 ​ *各…

ESP之经典蓝牙库BluetoothSerial介绍和实例演示

ESP之经典蓝牙库BluetoothSerial介绍和实例演示 1.概述 目前ESP32内置了双模蓝牙&#xff08;蓝牙4.0版本之前都是经典蓝牙&#xff0c;4.0版本成为BLT低功耗蓝牙转为物联网开发。双模指的就是这款芯片两种模式都支持&#xff09;。 这篇文章介绍ESP32蓝牙的经典模式使用方法…

算法学习day23

一、k个一组翻转链表 给你链表的头节点 head &#xff0c;每 k 个节点一组进行翻转&#xff0c;请你返回修改后的链表。 思路&#xff1a; 1.首先得到链表的长度size&#xff1b;然后在size>k的范围里面进行翻转长度为k的链表。 2.while(size>k) 在这个循环中&#xf…

【C++BFS算法】886. 可能的二分法

本文涉及的点 CBFS算法 LeetCod886. 可能的二分法 给定一组 n 人&#xff08;编号为 1, 2, …, n&#xff09;&#xff0c; 我们想把每个人分进任意大小的两组。每个人都可能不喜欢其他人&#xff0c;那么他们不应该属于同一组。 给定整数 n 和数组 dislikes &#xff0c;其…

电脑桌面记事本便签哪个好,有哪些好用的桌面备忘记事工具推荐

在寻找高效办公的道路上&#xff0c;我们经常需要记住许多重要的事情&#xff0c;然而人的记忆力终究有限&#xff0c;这时候就需要依赖一些工具来帮助我们进行提醒。一款好的电脑桌面记事本便签、桌面日程安排软件就像是一位得力助手&#xff0c;它不仅能够帮助我们合理规划时…

项目经理的开源工具指南:优化您的选择过程

国内外主流的10款开源项目管理系统对比&#xff1a;PingCode、Worktile、禅道、Teambition、Gogs、码云 Gitee、Jira、Redmine、ProjectLibre、OpenProject。 在选择合适的开源项目管理系统时&#xff0c;很多团队面临诸多挑战&#xff1a;功能是否全面&#xff1f;易用性如何&…

Excel模拟计算演示-以矩阵乘计算密度为例

Excel模拟计算演示-以矩阵乘计算密度为例 1.参考链接2.CUDA_Occupancy_Calculator截图3.矩阵乘计算密度模拟计算的操作步骤及效果 安装好CUDA之后,/usr/local/cuda-12.1/tools/CUDA_Occupancy_Calculator.xls里会看到"TABLE(,B17)"这样的表达式,原来是模拟计算的结果…

3V升5V输出800mA可驱动10MA驱动蜂鸣片芯片AH6910

135-3806-7573今天&#xff0c;我们将深入解析一款名为AH6910的芯片&#xff0c;这款芯片以其独特的3V至5V宽电压输入范围、800mA的高输出电流能力&#xff0c;以及能够轻松驱动低至10mA需求的蜂鸣片&#xff0c;成为了众多电子项目中的优选元件。######一、AH6910芯片概述 AH…

RIP路由协议

RIP-路由信息协议V1/V2/NG NG版为ipv6专用 距离矢量型IGP路由协议&#xff0c;使用跳数作为度量&#xff0c;支持等开销负载均衡&#xff1b;基于UDP&#xff0c;520端工作&#xff0c;基于UDP V1和V2的区别&#xff1a; 1、v1为有类别协议--不支持VLSM/CIDR&#xff0c;即使使…