提示:在查看Qt代码时,发现许多对象通过new的方式创建后,没有通过delete释放,让我产生疑问,是否会产生内存泄漏。
前言
Qt的内存管理机制,和智能指针不能说一模一样,只能说是完全相同。智能指针是我管理它,Qt的内存管理机制是它管理我。也就是智能指针反过来用。
提示:以下是本篇文章正文内容,下面案例可供参考
一、
Qt内存管理机制的发现:
我们在通过鼠标操作自己添加按钮在界面内时,一切正常:
那么是否可以自己通过模仿ui.h文件的写法,通过代码完成对按钮的放置呢?
这就是通过通过复制ui.h文件得到的代码,运行后发现没有出现按钮,需要调用show函数才可以显示,并且是以新窗口的形式出现的。这时候就出现了一个问题,为什么源代码没有show函数就可以显示,我没有show就不能显示,而且为什么会以新窗口的形式出现。
通过对比发现,我缩写的代码,在new时和源代码出现了差异。
pushButton_nextsong = new QPushButton(centralWidget);
pushButton_nextsong->setObjectName(QStringLiteral("pushButton_nextsong"));
它传了个参数。这就是为什么它不需要delete也不会内存泄漏的原因,这就是为什么它的按钮不会以新窗口出现的原因。
二、
Qt内存管理机制的原理:
通过帮助手册查看一下Qpushbutton的构造函数
会发现它的构造函数有个参数,是个QWidget类型的指针,默认值为NULL。
我们再查看QpushButton的继承关系,不难发现它继承了QAbstractButton,QAbstractButton又继承了QWidget,QWidget又继承了QObject。也就是说参数可以传一个父部件的指针或者说对象(不一定是继承关系)。这就是内存管理机制的核心。
我们通过帮助手册,查看其父部件QWidget的构造函数,发现了内存管理机制的秘密:
所以通俗的来说,就是给当前对象找了爹管理它,那么这个对象就会成为父部件的子部件,随着父部件出现而出现,父部件的关闭而关闭,而不需要单独delete。
总结:
内存管理和展示是不同的类去做的,展示是QWidget界面类去做,但是内存管理是QObject去完成的(Qt特有的类百分之90都继承了QObject)。所以说传参所传的父部件这个类不是随便传的,必须继承QObject这个类的才行。所以说展示的show和回收资源的delete是不同的类去完成的。
之所以说和智能指针一样,是因为在这里,我是将自己给到了QObject,那么QObject中有了我,在析构时就释放了我,所以是它管我。智能指针是我管他,创建在栈区,程序结束自动释放也是可以完成内存管理的。
这是后期添加:如何自己实现内存管理的功能。
Qt的内存管理是已经写好的框架,那么如何自己去写一段代码完成内存管理机制呢?
只需要自己写一个类(举个例子就叫它MyObject),所有需要进行内存管理的类继承自己写的MyObjiect。MyObject的实现我用代码说明
class MyObject
{
MyObject(MyObject *pr=NULL)
{
if(pr != NULL && !isOK)
{
pr->IO.insert(this);//传入需要被管理的指针,将其放到容器里去
isOK = true;//这个标志位是为了防止被重复管理
}
}
~MyObject()
{
if(isOK)
delete List;//这个写法不正确,只是为了理解,析构时释放掉容器内对应的指针指向的堆区空间
}
private:
List<MyObject *> IO;//通过容器存储需要管理的指针
bool isOK;
};