オブジェクト・ツリーと所有権

概要

QObjects オブジェクトはオブジェクトツリーで構成されます。他のオブジェクトを親に持つ を作成すると、そのオブジェクトは親の ()リストに追加され、親が削除されると削除されます。このアプローチは、GUIオブジェクトのニーズに非常によく合うことがわかりました。例えば、 (キーボード・ショートカット)は関連するウィンドウの子なので、ユーザーがそのウィンドウを閉じると、ショートカットも削除されます。QObject children QShortcut

QQuickItemQt Quickモジュールの基本的なビジュアル要素であるQt Quickは、QObject を継承していますが、QObject の親とは異なるビジュアル親の概念を持っています。アイテムの視覚的な親は、必ずしもオブジェクトの親と同じとは限りません。詳細は「概念 - Qt Quick のビジュアルペアレント」を参照してください。

QWidgetQt Widgets モジュールの基本クラスである Qt Widgets は、親子関係を拡張しています。つまり、親の座標系で表示され、親の境界によってグラフィカルにクリッピングされます。例えば、アプリケーションがメッセージ・ボックスを閉じた後に削除すると、メッセージ・ボックスのボタンとラベルも削除されます。

子オブジェクトを自分で削除することもできます。例えば、ユーザーがツールバーを削除すると、アプリケーションはそのQToolBar オブジェクトの1つを削除することになるかもしれません。その場合、ツールバーのQMainWindow 親はその変更を検出し、それに応じてスクリーン・スペースを再構成します。

デバッグ関数QObject::dumpObjectTree ()とQObject::dumpObjectInfo ()は、アプリケーションが奇妙に見えたり動作したりするときに、しばしば役に立ちます。

Qオブジェクトの構築/破壊順序

QObjects がヒープ上に作成されたとき(つまりnew で作成されたとき)、それらのオブジェクトから任意の順序でツリーを構築することができます。ツリー内のQObject が削除されるとき、そのオブジェクトに親があれば、デストラクタは自動的にそのオブジェクトを親から削除します。オブジェクトに子がある場合、デストラクタは自動的にそれぞれの子を削除します。破壊の順番に関係なく、QObject が2回削除されることはありません。

スタック上にQObjects が作成された場合も、同じ動作が適用されます。通常、破壊の順番は問題になりません。次のスニペットを考えてみよう:

int main()
{
    QWidget window;
    QPushButton quit("Quit", &window);
    ...
}

親であるwindow と子であるquit はどちらもQObjects である。なぜならQPushButtonQWidget を継承し、QWidgetQObject を継承するからである。quit C++言語標準(ISO/IEC 14882:2003)では、ローカル・オブジェクトのデストラクタはコンストラクタと逆の順序で呼び出されると規定されているからです。したがって、子オブジェクトであるquit のデストラクタが最初に呼び出され、window のデストラクタが呼び出される前に、親オブジェクトであるwindow から削除されます。

しかしここで、この2番目のスニペットに示されているように、構築の順序を入れ替えたらどうなるかを考えてみよう:

int main()
{
    QPushButton quit("Quit");
    QWidget window;

    quit.setParent(&window);
    ...
}

この場合、破壊の順番が問題になる。親のデストラクタが最初に呼ばれる。次に、その子であるquit のデストラクタを呼び出します。quit はローカル変数なので、これは正しくありません。その後、quit がスコープ外に出ると、そのデストラクタが再び呼び出され、今度は正しく呼び出されますが、ダメージはすでに終わっています。

本書に含まれる文書の著作権は、それぞれの所有者に帰属します 本書で提供されるドキュメントは、Free Software Foundation が発行したGNU Free Documentation License version 1.3に基づいてライセンスされています。 Qtおよびそれぞれのロゴは、フィンランドおよびその他の国におけるThe Qt Company Ltd.の 商標です。その他すべての商標は、それぞれの所有者に帰属します。