目录
Qt 的内存管理机制
Qt 的对象树
利用代码查看自动释放
Qt 的内存管理机制
Qt 的对象树
Qt 中所有的控件都是被一颗多叉树管理起来的,这样就是为了方便释放资源的时候方便释放,而我们在编写代码的时候,创建对应的控件,然后将对应的控件添加到 Qt 的对象树中,此时这个对象的释放问题也就不需要我们操心.
假设现在有一个 QWidget,然后这个 Widget 种还有一些其他的控件,里面有一个 QLabe、QPushButton、QListWidget,然后 QListWidget 中还有三个 Item 那么这个对象树是什么样子的呢?
此时我们看到的可能就是这样,那么此时的对象树是什么样子的呢?我们可以简单的画一下。
此时这就是 Qt 中对象树的样子。而我们释放这些控件的时候,当然也是希望一起释放的比较好,那么如果当一个控件提前就释放了呢?如果提前就释放了,那么当在界面上显示的时候,是没有该控件的,因为已经释放了当然也就是显示不出来的。
利用代码查看自动释放
既然我们知道了,当我们将一个控件加入到对象树的时候,这个对象就会合适的时候自动释放,那么首先什么是合适的时候呢?其实就是当我们关闭界面的时候,因为关闭界面了,说明我们已经不需要这个界面里面的控件显示了,所以我们理所当然的是可以将该控件释放掉的。
那么下面我们就写一个代码,我们自己写一个类,这个类继承自 QLabel,当然继承其他的可以挂到对象树上的类也是可以的,因为 QLabel 可以显示出来,所以我们创建一个类继承自 QLabel,然后我们重写这个类的析构函数,我们在这个类的析构函数里面添加一个打印语句,这样我们就可以在释放的时候看到是否释放了。
在看这个代码之前,我们在学习一下 Qt 中新建其他文件的方法,我们目前想要新建的是一个 C++ 文件,所以我们点击左上角的文件,然后点击新建文件。
然后我们选择 C++ ,然后在选择 C++ class,然后点击 choss ,后面就会弹出一个对话框。
等弹出这个对话框后,我们写想要的类名,以及想要继承类的名字,因为我们想要继承 QLabel,所以这里就选择 QLabel,然后点击next即可。
创建好后,这个就是我们创建类的头文件,不过这里选择继承的类并不会帮我们添加对应的头文件,所以我们需要自己添加基类的头文件。
创建好后,那么就可以了吗?其实并不行,我们前面说了,想要将一个对象挂到对象树上,那么这个就需要将这个对象的构造函数传入一个想要挂的对象的指针,而我们这个继承自 QLabel,所以我们就需要一个 QWidget 类型的指针,用来接收它的父节点的指针,然后用这个参数给MyLabel的基类来进行初始化。
#include "mylabel.h"
MyLabel::MyLabel(QWidget *parent)
:QLabel(parent)
{
}
那么下一步就是我们需要重写它的析构函数了,然后我们在它的析构函数里面添加一行打印语句,我们就可以看到析构的过程了。
MyLabel::~MyLabel()
{
qDebug() << "MyLabel 被析构";
}
在下一步,就是我们需要在 Widget 的构造函数中创建该对象,然后我们查看它的释放过程。
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
MyLabel* mylabel = new MyLabel(this);
mylabel->setText("Hello World");
}
下面我们就点击运行,当我们没有关闭界面的时候,mylabel 并不会析构,而是当我们点击关闭按钮后,mylabel 就析构了。