关于Qt的内存管理机制

  • Post author:
  • Post category:其他


提示:在查看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;
};



版权声明:本文为wlqxyl原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。