【问题标题】:Why connect `QThread::finished` signal to `QObject::deleteLater`?为什么将 `QThread::finished` 信号连接到 `QObject::deleteLater`?
【发布时间】:2022-01-07 14:15:00
【问题描述】:

我在QThread::finished 的 Qt 5.15 文档中阅读了此内容:

当这个信号发出时,事件循环已经停止运行。除了延迟删除事件外,线程中不会再处理任何事件。该信号可以连接到QObject::deleteLater(),以释放该线程中的对象。

但是,在文档的another section 中,它说

拥有该对象(或以其他方式访问该对象)的线程以外的线程对 QObject 调用 delete 是不安全的,除非您保证该对象是'此时不处理事件 [强调我的]。

如果我理解正确,在发出QThread::finished 之后,事件循环已经停止运行,并且如果不存在延迟删除事件(即QObject::deleteLater 没有被调用),线程中的所有对象也应该完成处理事件。那么,为什么还要为这些对象使用QObject::deleteLater 而不仅仅是手动删除它们呢?我使用QObject::deleteLater 没有问题;我只是确保我对 Qt 的理解是正确的。

【问题讨论】:

  • 您问是因为使用 deleteLater 有问题吗?还是只是为了您的理解?
  • 只是我的理解。我本来想把它放在我的帖子里,但我忘记了。我刚刚添加了它。

标签: c++ qt qt5


【解决方案1】:

QObject::deleteLater 在这种情况下本质上只是出于谨慎的考虑。如果您绝对确定不会访问对象,那么您没有理由不能简单地 delete 对象。

实际上,尽管您只需使用QObject::deleteLater 并让 Qt 为您处理它,与在运行时或退出时调试一些看似随机的崩溃的麻烦相比,因为碰巧有一个访问您手动删除的对象。

【讨论】:

  • deleteLater() 并不是解决取消引用悬空指针的万灵药——在 Qt 删除其引用对象后,悬空指针与您自己的代码删除引用时一样危险。 deleteLater() 确实 帮助(根据我的经验)是当您正在执行的方法被(直接或间接)从 您要删除的对象的方法调用时.在这种情况下,如果您只是删除对象,您几乎肯定会在您的方法返回并且调用方法尝试访问其(现已删除的)对象的成员变量时立即调用未定义的行为; deleteLater() 避免了这种情况。
  • 这当然是一个有效的场景,您必须使用deleteLater() 代替delete。我完全同意这不是万灵药,无论您如何清理对象,引用指针都存在固有风险。一般来说,为了安全起见,在deleteLater()delete 之后,我总是更喜欢将指针设置为nullptr,并在对指针的任何访问前加上nullptr 检查。我工作过的一些地方将其纳入了他们的编码标准,我发现它得到了回报,尽管有时看起来没有必要。
  • 我还认为将QThread::finished 连接到现有插槽可能比将其连接到自定义函数/函子更方便或更美观。
猜你喜欢
  • 2012-08-20
  • 2020-10-14
  • 1970-01-01
  • 2023-02-05
  • 1970-01-01
  • 2012-10-08
  • 2012-11-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多