QT内存知识点

2020-02-05  本文已影响0人  行走的代码

问题:为什么用deleteLater

20190117213922197.png
deletelater的原理是 QObject::deleteLater()并没有将对象立即销毁,而是向主消息循环发送了一个event,下一次主消息循环收到这个event之后才会销毁对象
由于事件队列中可能有引用该对象的地方,当deleteLater调用时,队列中引用该对象的事件会从队列中移除,从而确保最后释放对象时是安全的。

Qt半自动的内存管理:

在Qt中,以下情况下你new出的对象你可以不用亲自去delete:

  1. QObject及其派生类的对象,如果其parent非0,那么其parent析构时会析构该对象。
    原因:在Qt中,每个 QObject 内部都有一个list,用来保存所有的 children,还有一个指针,保存自己的parent。当它自己析构时,它会将自己从parent的列表中删除,并且析构掉所有的children。
  2. 有些类的对象可以接收设置一些特别的标记,比如:
    QWidget及其派生类的对象,可以设置 Qt::WA_DeleteOnClose 标志位(当close时会析构该对象)
    QAbstractAnimation派生类的对象,可以设置 QAbstractAnimation::DeleteWhenStopped
    QRunnable::setAutoDelete()
    MediaSource::setAutoDelete()
    ...

自动释放内存触发崩溃的实例:

实例1

#include <QApplication>
#include <QLabel>

int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QLabel label("Hello Qt!");
label.show();
label.setAttribute(Qt::WA_DeleteOnClose);
return app.exec();
}

运行正常,退出时会崩溃 ,因为label被close时,将会 delete 这儿label对象,但label对象却不是通过new分配到heap中的。
为了使得用户减少自己显式使用delete,Qt将delete隐藏的比较深。这样一来,不使用new为对象分配空间时,反倒需要多多小心了。

实例2

#include <QtGui>
int main(int argc, char* argv[])
{
   QApplication app(argc, argv);
   QLabel label(tr"Hello Qt!");
   QWidget w;
   label.setParent(&w);
   w.show();
   return app.exec();
}

因为退出时,w 比 label 先被析构,当 w 被析构时,会删除chilren列表中的对象,也就是这儿的 label。但 label 却不是通过new分配在heap中,而是在stack中,delte stack中的东西会导致崩溃。

QT内存管理机制:https://www.cnblogs.com/apocelipes/p/9991845.html

上一篇 下一篇

猜你喜欢

热点阅读