2016-07-03 40 views
4

我不明白Qt如何删除所有QObject的子元素,如果它是静态分配的话,没有双重删除。Qt如何处理堆栈分配的对象

基本上,如果我这样做,通常的方式,它看起来像这样:

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,还是我错过了什么?

+0

是的,你做错过的东西,即,不确定的行为是不确定的。 –

+3

@n.m .:这里没有什么不明确的地方,据我所知。 –

+1

@MattiVirkkunen在这个例子中可能没有定义,我只是说没有崩溃证明没有任何证据。 –

回答

8

QObject被销毁时,它将从其父母(如果它有)移除。因此,当销毁Window时,它不会销毁QPushButton,因为该按钮不再位于窗口的子项列表中。

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

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

+0

明白了。如果我在窗口前面创建按钮,然后使用button.setParent(&window),它确实会崩溃,这是很重要的。 这是如此...优雅:D – bisthebis

+0

@bisthebis“优雅”不是我会用到的词...混合RAII和'QObject'的育儿系统是不好的。还要注意,父子系统与智能指针一起工作同样糟糕,这是可惜的,因为它们是现代C++中的关键之一。 – rubenvb

+0

@rubenvb:好的,我必须承认这对于一致性并不好,但我很高兴不必把每个孩子都放在unique_ptr中。另一方面,当我有一个随机的非Qt对象作为我的窗口类的成员时,很难在使用unique_ptr或使其成为窗口的子项之间进行选择。你会建议Qt做什么? – bisthebis