概述
看多了Qt的代码就会发现,很多人的代码里大量使用new,却很少看到delete,以至于我刚学Qt时也养成了这个习惯,在写C++时也不用delete,结果造成很多麻烦。
原因在于Qt采用半自动的内存管理,不像c++那种全需要自己delete堆内存对象。Qt对象继承自QObject, QObject内部有一个list,会保存children,即QObjectList* children;还有一个指针保存parent,即QObject *parent。当此Qt对象执行析构函数时,它会将自己从parent的列表中删除,并且析构掉所有的children。
objParent有两个子对象objChild和objChild2,三者都继承自QObject,那么关系如下图:
半自动化的内存管理规则
QObject及其派生类的对象,如果其parent非0,那么其parent析构时会析构该对象。
QWidget及其派生类的对象,可以设置
Qt::WA_DeleteOnClose标志位,当close时会调用QWidgetPrivate::close_helper,进而调用deleteLater析构该对象。QAbstractAnimation派生类的对象,可以设置QAbstractAnimation::DeleteWhenStopped。QRunnable::setAutoDelete()、MediaSource::setAutoDelete()。父子关系:Qt特有的性质,与类的继承关系不同,注意二者要在同一线程。
使用如下:
QObject *p = new QObject();
MySon1 ps1(p);
MySon2* ps2 = new MySon2();
ps2->setParent(p);
注意要求是对象而不是指针,如果是指针就要用setParent函数。代码MySon2* ps2 = new MySon2(p);是不能实现自动析构的,会内存泄漏。
源码分析
构造函数
QObject构造函数部分代码:
if (parent) {
QT_TRY {
if (

本文探讨了Qt的半自动内存管理机制,指出在Qt中大量使用new却少用delete的原因。当QObject或QWidget对象析构时,它们会处理子对象的内存管理。然而,这种机制可能导致析构栈上对象的问题。文章通过源码分析,揭示了构造函数和析构函数的工作原理,并提出了针对潜在问题的改进方法。

762

被折叠的 条评论
为什么被折叠?



