概述
看多了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 (