Qt中QObject *parent内存释放注意事项

问题的出现的原因是我们对Qt半自动的内存管理的理解不够
在Qt中,一些情况下,不需要我们手动删除new出来的对象:
QObject及其派生类的对象,如果其parent非0,那么其parent析构时会析构该对象。

Qt中引入对象树
这里写图片描述
当一个 QObject 对象在堆上创建的时候,Qt 会同时为其创建一个对象树。不过,对象树中对象的顺序是没有定义的。这意味着,销毁这些对象的顺序也是未定义的。Qt 保证的是,任何对象树中的 QObject 对象 delete 的时候,如果这个对象有 parent,则自动将其从 parent 的 children() 列表中删除;如果有孩子,则自动 delete 每一个孩子。Qt 保证没有 QObject 会被 delete 两次,这是由析构顺序决定的。

(1)对于堆对象(new出来的对象):
①QObject *parent或者QWidget *parent,当指定了parent后,Qt就会自动管理该对象的释放,不需要我们手动delete
②不指定parent时,需要手动delete。

(2)栈对象:
③栈是“先入后出,后入先出”的方式,因此在创建栈对象的时候,要注意顺序,举一个例子说明:

错误的情况:

#include "widget.h"
#include <QApplication>
#include <QPushButton>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QPushButton btn;//先创建QPushButton
    Widget w;
    w.show();

    btn.setText("HelloWorld");
    btn.setParent(&w);//传入了w作为父窗口
    btn.show();
    return a.exec();
}

这里写图片描述
点击关闭,会出现:
这里写图片描述
改正后的(有几种改正方法,这里介绍一种):

#include "widget.h"
#include <QApplication>
#include <QPushButton>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();

    QPushButton btn;//将QPushButton的创建放在QWidget之后
    btn.setText("HelloWorld");
    btn.setParent(&w);//传入了w作为父窗口
    btn.show();
    return a.exec();
}

参考:
https://blog.csdn.net/taiyang1987912/article/details/29271549
https://blog.csdn.net/yeyiliang/article/details/50327991
https://blog.csdn.net/qq1623803207/article/details/77469672
https://blog.csdn.net/dbzhang800/article/details/6300025
https://blog.csdn.net/leonwei/article/details/3703598
对象树和拥有权:
https://www.cnblogs.com/King-Gentleman/p/4830978.html
https://blog.csdn.net/liang19890820/article/details/52414873

猜你喜欢

转载自blog.csdn.net/hp_cpp/article/details/80759379