【问题标题】:How does Qt handle stack-allocated objectsQt 如何处理堆栈分配的对象
【发布时间】:2016-07-06 23:11:33
【问题描述】:

我不明白 Qt 如何在静态分配的情况下删除所有 QObject 的子对象而不重复删除。

基本上,如果我按照通常的方式进行操作,它看起来像这样:

QWidget Window(nullptr);
QPushButton* button = new QPushButton(&Window);
Window.show();
return App.exec(); 
//When app ends, Window gets deleted 
//because it was statically allocated
//And then, Window deletes button because it's its child.

但我也可以做到这一点而不会崩溃:

QWidget Window(nullptr);
QPushButton button(&Window);
Window.show();
return App.exec(); 
//When app ends, button then Window get deleted 
//because they were statically allocated
//And then, Window (should) delete button AGAIN because it's its child, thus crashing 
//the program. But it doesn't. Why ?

Qt 知道我是如何创建 QPushButton 的吗,还是我错过了什么?

【问题讨论】:

  • 是的,你确实错过了一些东西,即未定义的行为是未定义的。
  • @n.m.:据我所知,这里没有任何未定义的内容。
  • @MattiVirkkunen 在这个例子中可能没有什么未定义的,我只是说没有崩溃证明什么。
  • @n.m.:那你可能想说那句话而不是说一些无关紧要的话。

标签: c++ qt


【解决方案1】:

QObject 被销毁时,它会从其父级中移除自己(如果有的话)。因此,当Window 被销毁时,它不会尝试销毁QPushButton,因为该按钮不再在窗口的子窗口列表中。

以下相关文档。它还提到如果对象的声明顺序与父/子关系顺序不匹配,则确实可能导致对象被销毁两次。这是一件坏事。

http://doc.qt.io/qt-5/objecttrees.html

【讨论】:

  • 知道了。可以检查如果我在窗口之前创建按钮,然后使用 button.setParent(&window),它确实会崩溃。它是如此......优雅:D
  • @bisthebis “优雅”不是我会用的词……将 RAII 和 QObject 的育儿系统混为一谈实在是太糟糕了。另请注意,父子系统与智能指针一起工作同样糟糕,这很遗憾,因为它们是现代 C++ 的基石之一。
  • @rubenvb :好吧,我必须承认这不利于一致性,但我很高兴不必将每个孩子都放在一个 unique_ptr 中。另一方面,当我有一个随机的非 Qt 对象作为我的窗口类的成员时,很难在使用 unique_ptr 或使其成为窗口的子级之间做出选择。你会建议 Qt 做什么?
猜你喜欢
  • 2014-05-30
  • 2013-01-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-17
  • 1970-01-01
  • 2020-08-24
相关资源
最近更新 更多