在Qt

问题描述

this post 中,我可以得出结论,在 Qt 中声明新小部件有两种主要方式(当然也可能有其他方式):

  1. 未使用 new 关键字:
QLabel lb;
lb.setText("a");
  1. 使用 new 关键字:
QLabel *lb = new QLabel;
lb->setText("a");

因此,在我的一些教程中,我看到讲师使用了第二种方式,之后没有使用 delete。从我从很多文章中读到的(例如 this),在使用 new 时,我们必须始终在此之后使用 delete,以避免内存泄漏。

但在阅读其他文章时,例如this article,他们提到:

只有在您的程序终止后,操作系统才能 清理并“回收”所有泄漏的内存。

在我的程序中,有时我确实使用 delete 当我想从桌子上完全蒸发掉某些东西时:

qformlayout *destroyAffineForm = inputFieldAffineBox->findChild<qformlayout*>("inputFieldFormBoxAffine",Qt::FindChildrenRecursively);
while (destroyAffineForm->count() > 0 && (child = destroyAffineForm->takeAt(0)) != nullptr)
{
    delete child->widget(); // delete the widget
    delete child;   // delete the layout item
}
delete destroyAffineForm;

但通常有很多小部件从程序开始到结束(没有我在最后调用 delete)一直保持原位,例如一个 QLabel 持有一些标题文本。

所以...总而言之,这些变量(在应用程序关闭之前一直存在于整个过程中)是否会造成内存泄漏,我必须插入一堆 delete 语句来释放它们,或者是操作系统最终会处理它吗? (我知道这可能是一个重复的问题,但我在这里得到了很多混合的陈述)

P.S:关于我的机器的一些信息

  • 在 64 位 Windows 10 上运行
  • Qt Creator 4.14.2
  • Qt 5.15.2 (MSVC 2019,64 位)

解决方法

所有 QObject 都会自动删除自己的子对象。 (请参阅文档 here。)QWidget 是 QObject。所以只要你建立了父子关系,你就不需要手动删除你的对象。为此,只需将指向父对象的指针传递给构造函数:

QLabel *label1 = new QLabel;   // <<- NEED TO DELETE
QLabel *label2 = new QLabel(some_parent_obj);   // Will be deleted when some_parent_obj is deleted