2016-04-15 16 views
7

C++のスタックにいつクラスを割り当てるべきですか?私はJavaの背景が強く、Javaではすべてのクラスがnewキーワードを使用してヒープ上に割り当てられています。 C++では、スタックとヒープの割り当てを選ぶことができますが、スマートポインタが導入されたので、所有権を転送しないものはすべてstd::unique_ptrで割り当てても意味があります。C++スタックとヒープの割り当て

スタック割り当てを使用する必要があるかどうかはまったく考えられません。埋め込みシステムで何らかの最適化が行われる可能性はありますか?

+2

「std :: unique_ptr」は単に「スタック」ベースのオブジェクトです。ところで、C++はスタックまたはヒープの概念を持たないため、自動オブジェクトと動的オブジェクトを呼び出します。あなたは可能であれば自動オブジェクトを使いたいと思っています。 – NathanOliver

+9

通常、逆の原則を使用します。動的割り当てが必要ない場合、あなたはそれをしません。動的割り当ては、デフォルトでは「早過ぎた悲観」です。 – molbdnilo

答えて

14

使用自動(スタック)割当たび関数スコープ - 又はforなどの制御ブロックの範囲、whileif等関数内 - オブジェクトが必要と寿命のための良好な一致です。こうすることで、オブジェクトが動的に割り当てられたメモリ、ファイルハンドルなどのリソースを所有/制御する場合、そのスコープが残されたときにデストラクタ呼び出し中に解放されます。 (ガベージコレクタが壊れてしまったあと、予期せぬ時間に)。

  • は、いくつかの他のコード

  • に所有権を引き渡すために、

    • 長い関数スコープよりも生きるためにオブジェクトを必要とする:明確な必要性があるかどう

      のみなど、newを使用

    • は、多態的に(つまり、仮想ディスパッチから派生クラスの関数実装を使用して)処理できる基本クラスへのポインタのコンテナを持つか、

    • スタックの多くを食べるだろう、特に大規模な割り当て(お使いのOS /プロセスは通常1-8 +メガバイトの範囲の上限を、「交渉し」ています)

      • これが唯一である場合ダイナミックメモリを管理するにはローカルstd::unique_ptr<>を使用し、スコープからの離脱に関係なくオブジェクトが解放されるようにする必要があります。 returnthrowbreakなど(class/structのデータメンバをstd::unique_ptr<>で使用して、オブジェクトが所有するメモリを管理することもできます)

    マシューヴァンNevelは約C++ 11の移動セマンティクス以下のコメント - 移動、関連性を使用して、動的に割り当てられた(ヒープ)大量のメモリを制御するスタックに小さな管理オブジェクトを持っている場合、すなわちセマンティクスは、管理オブジェクトがそのリソースを他のコード(多くの場合、呼び出し元であるが潜在的に他のいくつかのコンテナ/オブジェクトのレジスタ)によって所有されている別の管理オブジェクトに引き渡すときに、特別な保証ときめ細かな制御を与える。このハンドオーバは、一時的であっても、コピー/複製されているヒープ上のデータを回避することができる。さらに、elision戻り値最適化は、後でそこにコピーされるのではなく、最終的に割り当てられ/返されるメモリに、名目上の自動/スタックホスト変数を直接構築することができます。

    +0

    これは良いサマリーです。私は最近、非常に大きなオブジェクトの配列をスタックに入れていたコードをいくつか修正しました。慎重でない場合は、大きなプログラムでスタック領域を使い果たすか、深い再帰でスタック領域を使い果たすことができます。 –

    +0

    C++ 11のセマンティクに関するいくつかの詳細は、私が考えると完璧な答えになるでしょう:upvote –

    +0

    スタックの割り当ての代わりにstd :: unique_ptrを使うべき時を追加するとよいでしょう。 – KillerZefi

    1

    大きなコードベースでは、単純な構造体オブジェクトのスタック割り当てを使用しますが、より複雑なクラス(多態性、メモリ所有権など)では常に動的割り当てを使用します。

    関連する問題