12

以前は、クラスのインスタンスを作成する必要があるときはいつでも、new を使用してそれをヒープに割り当てていました (stl クラス、および vec3 や mat4 などの数学クラスを除く)。

しかし、コードの一部を批判的に見ていたところ、技術的にはこれらのクラスをスタック上に作成するだけでよいことに気付きました。それらはそれほど大きくなく、現在のスコープ外で変更する必要はありません。(時折) それらを別の関数に渡す必要がある場合、ポインターを渡すのと同じくらい簡単に参照を使用できます。

以前は常にデフォルトでヒープに割り当て、特定の場合にのみスタックを使用していましたが、スタックにデフォルトで割り当てて、ヒープを使用する場合にのみヒープを使用する方がよいかどうか疑問に思っています。

  • ポインターが本当に必要です (つまり、オブジェクトの有効期間が宣言のスコープよりも長く続く)
  • クラスまたは配列がスタックに対して大きすぎます
  • 継承にはそれが必要です (抽象基本クラス/インターフェース)
  • 他の何か?

また、これは疑問を投げかけます: スタックに合理的に割り当てるには (おおまかに) 大きすぎるクラスはどれくらいですか? (少なくとも、スマートフォンとハイエンド デスクトップに取り組んでいると仮定します) スタック サイズの制約について不必要に心配しているだけですか? (おそらく、大規模な配列について話しているのでない限り、またクラスが 1 キロバイトに近くならない限り)

4

4 に答える 4

8

デフォルトの動作は次のとおりです。

オブジェクトの寿命が特定のスコープと一致している場合、
つまりコンパイル時に簡単に決定できる場合

次に、自動保存期間オブジェクト(スタックのような)である必要があります

オブジェクトの寿命が実行時に定義され、現在のスコープを超えている場合

次に、動的ストレージ期間オブジェクト(ヒープのような)である必要があります

注:すべての動的ストレージ期間オブジェクトは、適切なRAIIクラスでラップすることにより、ライフスパンを制御する必要があります。通常、これは次のことを意味します。単一のオブジェクトの場合はスマートポインタですが、複数のオブジェクトは最終的にコンテナに入れられます。

私は物事がスタック対ヒープとして定義されるのを見たくありません。それは状況の本当の意味を伝えていないので。

 int x;       // its on the stack
 struct X
 {
     int x;   // Is this a stack or heap object?
 }            // It depends on its parent.


 // But in both cases it is an automatic storage duration object.
 // In both cases the lifespan's are well defined.
 //     The first is defined by the scope it is declared within.
 //     The second is defined by the lifespan of its parent.

自動/動的な「保存期間」オブジェクトの観点から考える必要があります。これは、言語の正しいセマンティクスを伝えます。

他に2つのタイプの変数があるため、4つの異なるタイプの変数が作成されることに注意してください。自動/動的/静的/スレッド'ストレージ期間'オブジェクト。

于 2012-09-08T18:03:21.997 に答える
5

私は2つの理由から、スタックに割り当てることを好みます。まず、他のすべてが等しい場合、ヒープよりも高速です。また、割り当て解除は自動的に行われるので、覚えておく必要はありませんdelete(もちろん、それauto_ptrを支援するためのsなどがあります)。

ポインタが本当に必要です

スタック上のオブジェクトへのポインタを渡してもかまいません。有効期限が切れた後、そのポインタのユーザーがオブジェクトにアクセスしないようにしてください。

クラスまたは配列がスタックに対して大きすぎます

これが問題になるのは、本当に大きなことだけです。おそらく1MBのスタックがあるので、問題が発生する前に約1000個の1KBオブジェクトを配置できます。

継承にはそれが必要です

なぜだろう?

他に何かありますか?

オブジェクトに必要な有効期間は、スタックフレームの有効期間よりも長くなります。これが、ヒープに割り当てる主な理由です。

于 2012-09-08T17:52:10.670 に答える
-2

メモリを動的に割り当てる必要がある場合にのみ、ヒープに割り当てます。つまり、コンパイル時にどれだけ割り当てる必要があるかわからないということです。それ以外の場合はスタックに割り当てます

于 2012-09-08T17:48:58.587 に答える