(六)Qt内存管理

父子关系:

所有指定了父对象的Qt对象(继承自QObject类的实例)与其父对象间存在父子关系:

每个Qt对象都保存有指向其所有子对象的指针

每个Qt对象都有一个指向其父对象的指针

(六)Qt内存管理_第1张图片

指定(通过构造函数指定,或通过setParent函数)Qt对象的父对象时:

其父对象会在子对象链表中加入指向该对象的指针

该对象会保存指向其父对象的指针

 

当Qt对象被销毁时

该对象会将自己从父对象的子对象链表中移除

该对象会将自己的子对象链表中所有子对象销毁

 

通过父子关系得到Qt对象树,删除树中的节点时会导致对应的子树被销毁

 (六)Qt内存管理_第2张图片

设置属性:

如: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

 

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实验分析教程》创作,并根据自身理解对其进行了少许的扩展

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(Qt)