14

Qt では、コンポジションを介して親に子ウィジェットを埋め込むことができますか、それとも で作成する必要がありnewますか?

class MyWindow : public QMainWindow
{
    ...
private:
    QPushButton myButton;
}

MyWindow::MyWindow ()
 : mybutton("Do Something", this)
{
   ...
}

QObjectドキュメントによると、親が破棄されると、から派生したオブジェクトは自動的に破棄されます。これdeleteは、上記の例ではクラッシュする への呼び出しを意味します。

以下を使用する必要がありますか?

QPushButton* myButton;

myButton = new QPushButton("Do Something", this);

編集

答えは非常に多様で、基本的に 3 つの可能性に要約できます。

  • はい、構成は問題ありません。Qt は、オブジェクトがどのように割り当てられ、ヒープに割り当てられたオブジェクトのみを把握できdeleteます (これはどのように機能しますか?)
  • はい、構成は問題ありませんが、親を指定しないでください。そうしないと、親がdeleteオブジェクトを呼び出すためです (しかし、親のないウィジェットはトップレベル ウィンドウに変わりませんか?)
  • いいえ、ウィジェットは常にヒープを割り当てる必要があります。

どちらが正しいですか?

4

7 に答える 7

7

非静的、非ヒープメンバー変数は、その特定のオブジェクトの削除シーケンスが開始されるときに削除されます。すべてのメンバーが削除された場合にのみ、基本クラスのデストラクタに移動します。したがって、QPushButton myButtonメンバーは、〜QMainWindow()が呼び出される前に削除されます。また、QObjectのドキュメントから:「親の前に子オブジェクトを削除すると、Qtはそのオブジェクトを親の子のリストから自動的に削除します」。したがって、クラッシュは発生しません。

于 2011-06-03T11:49:31.820 に答える
4

オブジェクトツリーと所有権があなたの質問に答えます。基本的に、子オブジェクトがヒープ上に作成されると、その親によって削除されます。

一方、子オブジェクトがスタック上に作成される場合、破棄の順序が重要です。子は親のに破棄され、デストラクタが2回呼び出されないように、親のリストから自分自身を削除します。

そのリンクには、問題のある破壊の順序を示す例もあります。

于 2011-06-03T11:49:01.243 に答える
4

ドキュメントによると、 QObject から派生したオブジェクトは、その親が破棄されると自動的に破棄されます。これは削除の呼び出しを意味します

いいえ。これは、その特定のエンティティのデストラクタへの呼び出しを意味します。

あなたの例では、MyWindowが破壊された場合、それはのデストラクタMyWindowが呼び出されたことを意味します。myButton次に、すでに実装されているデストラクタを呼び出しますQPushButton

複合エンティティがある場合、そのエンティティでデストラクタのみが呼び出されますが、呼び出されないdeleteため、クラッシュしません。

Qt の親子関係は、特にスタックまたはヒープ内にある必要はありません。それは何にでもありえます。

スタック上の親子関係の同様の例はこちらです。

HTH..

于 2011-06-03T08:39:47.917 に答える
2

オブジェクトは、親ポインターがある場合にのみ破棄されるため、次を使用できます。

MyWindow::MyWindow ()
 : mybutton("Do Something", 0)
{
   ...
}
于 2011-06-03T07:56:29.193 に答える
0

オペレーターを呼び出しdeleteてもアプリケーションはクラッシュしません。次の引用を読むことができます

Qt の親子メカニズムは QObject に実装されています。親を持つオブジェクト (ウィジェット、バリデータ、またはその他の種類) を作成すると、親はオブジェクトをその子のリストに追加します。親が削除されると、子のリストを確認し、各子を削除します。次に、子自体がすべての子を削除し、子がなくなるまで再帰的に削除します。親子メカニズムにより、メモリ管理が大幅に簡素化され、メモリ リークのリスクが軽減されます。delete を呼び出さなければならないオブジェクトは、new で作成し、親を持たないオブジェクトだけです。また、親の前に子オブジェクトを削除すると、Qt はそのオブジェクトを親の子のリストから自動的に削除します。

親引数はNULLデフォルト (デフォルト引数) であることに注意してください。これは QPushButton コンストラクターです。

QPushButton ( const QString & text, QWidget * parent = 0 )

だからあなたは使うことができます

    MyWindow::MyWindow () : mybutton( new QPushButton( "Do Something") ){   ... }

deleteそして、いつでも任意のコンポーネントを呼び出すことができます

Qtはこの点を処理します

于 2011-06-03T08:17:10.270 に答える
0

QObject はそれを破棄するため、ヒープ上に作成する必要があります。

class MyWindow : public QMainWindow
{
    ...
private:
    QPushButton *myButton;
}

MyWindow::MyWindow ()
 : mybutton( new QPushButton( "Do Something", this) )
{
   ...
}
于 2011-06-03T07:56:50.423 に答える