赞
踩
父子关系:
所有指定了父对象的Qt对象(继承自QObject类的实例)与其父对象间存在父子关系:
每个Qt对象都保存有指向其所有子对象的指针
每个Qt对象都有一个指向其父对象的指针
当指定(通过构造函数指定,或通过setParent函数)Qt对象的父对象时:
其父对象会在子对象链表中加入指向该对象的指针
该对象会保存指向其父对象的指针
当Qt对象被销毁时
该对象会将自己从父对象的子对象链表中移除
该对象会将自己的子对象链表中所有子对象销毁
通过父子关系得到Qt对象树,删除树中的节点时会导致对应的子树被销毁
设置属性:
如:QWidget及其子类对象,可以设置Qt:: WA_DeleteOnClose,此后,当被close时便自动销毁(delete)
使用函数QObject类的成员函数deleteLater():
使用此函数后销毁操作不会立即执行,而是当Qt对象返回事件循环时执行销毁操作(如果事件循环未开始,将立即执行销毁操作),多次调用此函数是安全的
注意:
(1)想要设置Qt::WA_DeleteOnClose,被设置对象必须位于堆,否则触发delete时会作用在栈上,程序将会崩溃
(2)、尽量依靠Qt对象间的父子关系销毁对象,不要手动去delete。正常情况下,发生delete时,被delete的父对象会知道这个事情,并会将被delete的子对象从其子对象链表移除,但如果一个Qt对象正在接受事件队列的中途被delete,结果可能是内存的多次释放,如果一定要销毁,使用deleteLater()
(3)、尽量不要在一个Qt对象的父对象之外持有指这个Qt对象的指针,因为这个指针在某些时刻指向的Qt对象可能已经被销毁,应该使用智能指针QPointer(此指针会在其指向的Qt类对象(只能指向QObject及其子类对象)被销毁时自动置NULL)
(4)、注意一个因为父子关系而引出的问题:
#include <QtGui>
int main(int argc, char *argv[])
{
QApplicationa(argc, argv);
QLabellabel("Hi");
QWidgetw;
label.setParent(&w);
w.show();
returna.exec();
}
问题在于:退出时w比label先析构,w是label的父对象,由于父子关系,w析构时,其操作之一是销毁子对象(执行delete),而label是栈对象,这一动作将导致程序崩溃,解决办法(1)、使label对象在堆上创建
(2)、确保label比w先被析构,label会将自己从w的子对象链表中移除,w析构时其子对象链表中已经不存在label
将代码的顺序改为:
QWidget w;
QLabel label("Hi");
声明:
此文根据 狄泰学院唐老师的《QT实验分析教程》创作,并根据自身理解对其进行了少许的扩展
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。