QT的内存回收机制
- QT中内存回收的本质
Qt中有内存回收机制, 但是不是所有被new出的对象被自动回收, 满足条件才可以回收
如果想要在Qt中实现内存的自动回收, 需要满足以下两个条件:
- 创建的对象必须是QObject类的子类(间接子类也可以)
- 创建出的类对象, 必须要指定其父对象是谁, 一般情况下有两种操作方式:
对于1:
QObject类是没有父类的, Qt中有很大一部分类都是从这个类派生出去的
Qt中使用频率很高的窗口类和控件都是 QObject 的直接或间接的子类
对于2:
// 方式1: 通过构造函数
// parent: 当前窗口的父对象, 找构造函数中的 parent 参数即可
QWidget::QWidget(QWidget *parent = Q_NULLPTR, Qt::WindowFlags f = Qt::WindowFlags());
QTimer::QTimer(QObject *parent = nullptr);
// 方式2: 通过setParent()方法
// 假设这个控件没有在构造的时候指定符对象, 可以调用QWidget的api指定父窗口对象
void QWidget::setParent(QWidget *parent);
void QObject::setParent(QObject *parent);
对于窗口类,QWidget是所有类的父类,使用QWidget *parent 父类指针指向子类对象
对于其他类,QObject 是所有类的父类,使用QObject *parent父类指针指向子类对象
主要就是这两种父类指针,父类指针创建的目的很大程度上就是为了资源回收。
当父对象析构的时候,先把所有的子对象析构,最后在析构父对象。
QT中内存回收的本质
当你创建一个QObject对象时,会看到QObject的构造函数接收一个QObject指针作为参数,这个参数就是 parent,也就是父对象指针。这相当于,在创建QObject对象时,可以提供一个其父对象,我们创建的这个QObject对象会自动添加到其父对象的children()列表。当父对象析构的时候,这个列表中的所有对象也会被析构。
任何对象树中的 QObject对象 delete 的时候,如果这个对象有 parent,则自动将其从 parent 的children()列表中删除;如果有孩子,则自动 delete 每一个孩子。Qt 保证没有QObject会被 delete 两次,这是由析构顺序决定的。
当父对象析构的时候,先把所有的子对象析构,最后在析构父对象。
关闭主窗口:
日志应该反着看,因为先是调用了mianwindow的析构函数,先打印了 ”析构主窗口“,然后通过delete ui调用了子类d1的析构,d1又调用了d2的析构(先析构子类,再析构父类)
参考文章