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 内存了。 

        

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大卫的纯爱战士

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值