2012-01-31 15 views
2

私がしようとするとCButton btn;などのGUIボタンCButtonを定義した場合、私は、スタックなぜ、多くのGUI CObjects(CButton)をスタックではなくヒープに置く必要があるのですか?

にそれを置くことを試みた。しかし、私はCButton *btn = new CButton();を行う場合には動作し、これは、ヒープ上に置かれているので、私は>エラー - を取得します。

CButtonオブジェクトをスタックに配置できないのはなぜですか?

+0

あなたはどのライブラリを使用していますか?これらの 'CButton'オブジェクトはどこから来ますか?このMFCですか、それとも全く別のものですか?あなたはどんなエラーを受け取りますか? –

+2

この決定は、ヒープまたはスタックに関するものではありません。これは、保存期間、多分多形性に関するものです。また、メモリリークやその他の問題につながる可能性があるため、このように「裸」の「新」を使用しないでください。 –

答えて

3

これは保存期間の問題です。 MFCを使用すると、CButtonの目的はユーザーがクリックできるようになり、イベントを生成して処理することができます。このすべては、CButtonのライフタイムが、それを作成する関数の存続期間を超えて延長されなければならないことを示しています。一般的なMFCダイアログクラス(CDialog)では、CButtonはメンバー変数なので、そのライフタイムはクラスインスタンスの有効期間です。代わりにコンストラクタにCButton変数を宣言すると、コンストラクタが終了すると破棄されスコープ外になります。

ランタイムまでに判明していない決定に基づいてボタンを作成したい場合があります。その場合、裸の「新」を使用しないという上記のコメントは重要です。スマートポインタ(またはスマートポインタのコンテナ)を使用して作成したCButton *を保持すると、自動的にクリーンアップされます。これらのスマートポインタまたはコンテナは、クラススコープで作成する必要があります。

+0

これらのウィンドウラッパークラスの多くのデストラクタは、必ずしもネイティブウィンドウを削除するとは限りません。 C++オブジェクトの作成とWindowsオブジェクトの作成は、MFCの世界では同等ではありません。 –

1

MFCは分かりませんが、スタックに割り当てられているCButtonが破壊されて破棄されると思います。
他の場所からこのボタンのインスタンスにアクセスすると、アクセス違反が発生します。

1

1)他の多くの人が回答したように、変数のスコープと関係しています。関数をローカルにすることで、関数が終了するとその関数は終了します。

2)スタックスペースはヒープスペースよりもはるかに制限されており、特に複数のスレッドがあります。典型的なwin32プロセスは、1メガバイト未満のスタック割り当てを持っていますが、数千メガバイトのヒープを持つことができます。

4

私は他の場所で見たことがないMFCの共通のイディオムがあります。自動的にクリーンアップされる「一時的な」オブジェクトを作成することは可能です。クリーンアップは、メッセージループなど、MFC処理の特定の段階で発生します。

CButton * btn = (CButton *) FromHandle(hwnd); 

FromHandle機能はCWndオブジェクトへのポインタを返しますが、そのオブジェクトがどこから来たのか、あなたは知りません。 ではありません。ポインタを削除しようとし、現在のスコープを超えて有効なポインタに依存しないでください。それをメンバー変数に保存しないでください! MFCは必要に応じてオブジェクトを削除します。

関連する問題