问题的出现的原因是我们对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