オブジェクトツリーと所有権
概要
QObjects オブジェクトはオブジェクトツリーとして構成されます。あるオブジェクトを親としてQObject を作成すると、その は親のchildren()リストに追加され、親が削除されるとともに削除されます。このアプローチは、GUIオブジェクトの要件に非常に適していることがわかります。 たとえば、QShortcut (キーボードショートカット)は関連するウィンドウの子であるため、ユーザーがそのウィンドウを閉じると、ショートカットも削除されます。
QQuickItem Qt Quick モジュールの基本的な視覚要素である`Item`は、` `を継承していますが、その「QObject視覚的な親」という概念は、` `の親とはQObject 異なります。`Item`の視覚的な親は、必ずしもそのオブジェクトの親と同じであるとは限りません。詳細については、 の「Concepts - Visual Parent」Qt Quickを参照してください。
QWidget、Qt Widgets モジュールの基底クラスである`Item`は、親子関係を拡張しています。子ウィジェットは通常、子ウィジェットとしても機能します。つまり、親の座標系に表示され、親の境界によってグラフィカルにクリップされます。 たとえば、メッセージボックスが閉じられた後にアプリケーションがそれを削除する場合、ボタンやラベルはメッセージボックスの子であるため、期待どおり、メッセージボックスとともに削除されます。
子オブジェクトを自分で削除することも可能で、その場合、子オブジェクトは親から自動的に切り離されます。例えば、ユーザーがツールバーを削除すると、アプリケーションがそのQToolBar オブジェクトの1つを削除することになります。その場合、ツールバーの親であるQMainWindow が変更を検知し、それに応じて画面領域を再構成します。
アプリケーションの動作や表示に異常が見られる場合、デバッグ関数 `QObject::dumpObjectTree()` および `QObject::dumpObjectInfo()` が役立つことがよくあります。
QObjectの生成・破棄順序
QObjects がヒープ上に生成される場合(つまり、new を使って生成される場合)、それらから任意の順序でツリーを構築することができ、後でツリー内のオブジェクトを任意の順序で破棄することができます。 ツリー内のQObject が削除される際、そのオブジェクトに親が存在する場合、デストラクタは自動的にそのオブジェクトを親から削除します。また、そのオブジェクトに子が存在する場合、デストラクタは自動的に各子を削除します。削除の順序にかかわらず、QObject が2回削除されることはありません。
QObjects がスタック上で生成された場合も、同様の挙動が適用されます。通常、破棄の順序は依然として問題にはなりません。次のコード例を考えてみましょう:
int main()
{
QWidget window;
QPushButton quit("Quit", &window);
//...
}親の `window` と子である `quit` は、どちらも `QObjects ` です。これは、`QPushButton ` が `QWidget` を継承し、`QWidget ` が `QObject` を継承しているためです。このコードは正しいです。C++ 言語規格(ISO/IEC 14882:2003)では、ローカルオブジェクトのデストラクタはコンストラクタの逆順で呼び出されると規定されているため、`quit ` のデストラクタが 2 回呼び出されることはありません。 したがって、子オブジェクトであるquit のデストラクタが最初に呼び出され、window のデストラクタが呼び出される前に、親オブジェクトであるwindow から自身を削除します。
しかし、2つ目のスニペットに示されているように、生成の順序を入れ替えた場合、何が起こるかを考えてみましょう:
int main()
{
QPushButton quit("Quit");
QWidget window;
quit.setParent(&window);
//...
}この場合、破棄の順序が問題を引き起こします。親オブジェクトは最後に生成されたため、そのデストラクタが最初に呼び出されます。その後、親オブジェクトは子オブジェクトのデストラクタquit を呼び出しますが、quit はローカル変数であるため、これは不正な動作です。その後、quit がスコープ外になると、そのデストラクタが再度呼び出されます。この時の呼び出しは正しいものの、その時点で既に問題が生じてしまっています。
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.