20

私はしばらくQtをプログラミングしてきましたが、これら2つのケースの違いは何なのか疑問に思っています:

ケース1:

ヘッダ:

QPushButton * button;

ソースファイル:

button = new QPushButton(this);
button->setText("Button");
button->resize(100,100);

ケース 2:

ヘッダ:

QPushButton button;

ソース:

button.setParent(this);
button.setText("Button");
button.resize(100,100);

どちらもボタンを生成しますが、前者はいつ使用し、後者はいつ使用する必要がありますか? そして、2つの違いは何ですか?

4

5 に答える 5

15

最初のケースと 2 番目のケースの違いは、ポインターとnewステートメントを使用してボタンを割り当てる場合、ボタンのメモリが空きストア (ヒープ) に割り当てられることです。2 番目のステートメントでは、メモリがスタックに割り当てられます。

スタックではなくフリー ストアにメモリを割り当てる理由は 2 つあります。

  1. スタックのサイズは限られているため、スタック バジェットを使い果たすと、プログラムはスタック オーバーフローでクラッシュします。フリー ストアにさらに多くのメモリを割り当てることができます。メモリの割り当てに失敗した場合、通常はbad_alloc例外がスローされるだけです。
  2. スタック上の割り当ては厳密に後入れ先出し (LIFO) です。つまり、ボタンは{...}、メモリを割り当てたコード ブロック (間のもの) より長く存在することはできません。フリー ストアにメモリが割り当てられると、プログラマはメモリが有効である時間を完全に制御できます (ただし、不注意によりメモリ リークが発生する可能性があります)。

あなたの場合、呼び出し関数の期間中だけボタンが存在する必要がある場合は、スタックにボタンを割り当てても問題ないでしょう。ボタンをより長く有効にする必要がある場合は、無料のストアに固執します

于 2013-09-11T16:01:23.927 に答える
7

親オブジェクトが破棄時に子オブジェクトを自動的に削除する場合、Qtメモリ管理はオブジェクトの階層で機能します。これが、同様のケースで Qt プログラムが常にポインターを使用する理由です。

Qt によるメモリ管理:

Qt はオブジェクトの階層を維持します。ウィジェット (可視要素) の場合、これらの階層はウィジェット自体の積み重ね順序を表し、非ウィジェットの場合、単にオブジェクトの「所有権」を表します。Qt は子オブジェクトを親オブジェクトと一緒に削除します。

于 2013-09-11T15:57:41.403 に答える
2

最初のケースでは、ボタンを動的に割り当てています (つまり、親が破棄されるとボタンも破棄されます)。2 番目のケースでは、コード ブロックが終了するとボタンが消えます (範囲外になることを意味します)。

QObjectあなたが参照している、それが作成されたブロック以上のものを持続させたい場合は、最初のものを使用してください。

参照しているクラスのコンテキストでは (buttonどちらの場合もメンバー変数であると仮定して)、大きな違いはありません。

また、ポリモーフィズムを使用するときにポインターを使用することもできます。

于 2013-09-11T15:55:50.597 に答える
1

便利な特定の使用法: カスタム イベントを投稿するとき、詳細なデータを運ぶとき、たとえば:

/** support SWI... prolog_edit:edit_source(File) */
struct reqEditSource : public QEvent {
    QString file;
    QByteArray geometry;
    reqEditSource(QString file, QByteArray geometry = QByteArray())
        : QEvent(Type(User+1)), file(file), geometry(geometry) {}
};

それらを「起動して忘れる」ことができます:

qApp->postEvent(this, new reqEditSource(files[i], p.value(k).toByteArray()));

イベントは配信後に削除されます。

于 2013-09-11T17:16:17.703 に答える