2016-07-03 10 views
4

静的に割り当てられていた場合、Qtのすべての子を削除することができません。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を破壊しようとしません。

以下の関連ドキュメントまた、オブジェクトの宣言順序が親子関係の順序と一致しない場合、実際にはオブジェクトが2度破棄される可能性があるということも言及しています。それは悪いことです。

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

+0

入手しました。私がウィンドウの前にボタンを作成してから、button.setParent(&window)を使用すると、実際にクラッシュすることを確認するのは辛かったです。 それはとてもエレガントです:D – bisthebis

+0

@bisthebis "エレガント"は私が使用する言葉ではありません... RAIIとQObjectの両親のシステムを混ぜるのは悪いことです。また、親子システムは、現代のC++のキーストーンの1つであるので、残念ながらスマートポインタと一緒に悪いことにも注意してください。 – rubenvb

+0

@rubenvb:まあ、それは一貫性のためには良くないと認めなければなりませんが、すべての子供をunique_ptrに入れなくても大丈夫です。逆に、私のウィンドウクラスのメンバーとして、ランダムで非Qtのオブジェクトを持っているときは、unique_ptrを使うか、ウィンドウの子にするかを選ぶのは難しいです。 Qtに何をお勧めしますか? – bisthebis

関連する問題