2012-09-17 15 views
7

私はデータ構造体クラスを取っています。教授からのすべての例では、常にマップに構造体やコンテナへのポインタの値を設定します。構造物または容器自体を保持することに反対する。ポインタのマップと構造体/コンテナのマップ(C++)

彼はちょうど習慣としてそれをやっているのですか、スピードアップなどの理由がありますか?

  • 私はデータへのポインタを使用してデータの重複コピーを避けることができますが、同時に複数のコンテナ/構造のそのデータへの家の指示を避けることができます。
  • これらの例では、それは事実に注意してください。データはそのマップ内にのみあります。
+2

教授に質問してみませんか?これは勉強にならない質問です。 – John3136

+0

私は15年以上のプロのC++開発と100万行以上のコードを職務に書いていますが、コンテナの内部に構造体やクラスを置くことはめったにありません。私が何らかの種類のポインタを使用している時間の99%以上(最近はスマートポインタとなる可能性が高い)。 – drescherjm

+0

私はすでに回答していますが、その質問をhttp://stackoverflow.com/questions/141337/c-stl-should-i-store-entire-objects-or-pointers-toの複製と見なすべきかどうか疑問です-objects。 – jogojapan

答えて

9

私はそれを見ると、ポインタ対オブジェクトを使用するかどうかを決定する際に関与する因子の数があります

1.あなたをするか、またはあなたが多型を必要としませんか?

基本クラスオブジェクトのコンテナを維持するが、さまざまな派生クラスのオブジェクトを格納する場合は、仮想関数呼び出しが正しく解決されないため、ポインタを使用する必要があります。ポインタがオブジェクトにpreferrableかもしれ主な理由の

2.保存したオブジェクトのサイズとコピー操作のための適性

一つのコンテナで行われる様々な操作がのコピーを作成伴うということですオブジェクトに格納されます。これは、多くの格納操作(例えば、std::vector<>::push_back()またはstd::map<>::insert())、いくつかの検索操作(例えば、std::vector<>::operator[]、およびそのオブジェクトをローカル変数に格納する)、およびコンテナによって実行される操作のいくつかが「内部的に」(例:ベクトルがその容量を超えて拡大したときのベクトルの再割り当て、またはstd::unordered_map<>の再ハッシュコピー操作は、コンテナをどのように選択し、そのコンテナをどのように使用するかによってはあまり重要ではないことに注意してください。std::vector<>::reserve()を使用して十分なスペースを割り当て、記憶にはstd::vector<>::emplace_back()を使用し、検索された要素のローカルコピーを作成しないことは、コピーが作成されていないことを意味する可能性があります)。

しかし、多数のコピーを作成する(または既存のコードをプロファイリングすると多くのコピーが作成されることがわかっている)場合は、オブジェクトの代わりにポインタを使用すると、ポインタが小さくてメモリ内で整列しているようになることは明らかです。そして、あなたが格納しているオブジェクトがポインタよりも実際に小さい場合、これはやはり意味をなさないでしょう。あなたは、コンテナとその内容

に行う

3.その他の操作、あなたが扱っているオブジェクトはポインタよりも大きいと、あなたはコピー操作にかなりの量を期待していても、ポインタを使用することは必ずしもpreferrableではありません。多数の中型オブジェクト(それぞれ16バイト)を格納し、コンテナ全体を繰り返し処理し、何らかの統計計算を実行する必要がある場合を考えてみましょう。これらのオブジェクトをベクタに直接格納すると、反復処理中にキャッシュの効率が大幅に向上します。オブジェクトを1つ取得すると、キャッシュライン全体がメモリから取得されるため、次のオブジェクトの取得がはるかに高速になります。ポインタを使用する場合は一般的にそうではありません。逆に、要素を検索した後、ポインタを参照解除しなければならない可能性があるメモリ領域から別の移動操作を引き起こす必要があります。

これは明らかに、格納するオブジェクトのタイプとサイズ、実行する操作のタイプと頻度によって異なります。あなたが扱っているオブジェクトが、GUIアプリケーションのさまざまなタイプのウィンドウ、ボタン、およびメニューである場合は、ポインタを使用して多態性を利用したいと思うでしょう。一方、コンパクトな要素の巨大な構造(大きさと形状がすべて同じ)を処理している場合や、頻繁に反復処理や一括コピーを行う操作では、オブジェクトを直接格納することができます。両方を試したり、メモリと時間ベンチマークの結果に基づいて決定したりすることなく、決定が難しい状況もあります。最後の注意として


あなたは、ポインタを使用して終了ならば、あなたが構築しているコンテナを使用すると、ヒープ上に割り当てているオブジェクトの究極の所有者であるか、単に一時的なポインタを維持しているかどうかを検討します。コンテナがそれらのオブジェクトの所有者である場合、生のポインタよりもスマートポインタを使用することをお勧めします。

1

コンテンツタイプがコピー可能でない可能性があります。

1

オブジェクトインスタンスをコンテナに直接格納する利点は、ポインター自体が使用するスペースを節約して間接レベル&を回避することです。 は、両方の時間に関して勝利&ポインタを格納する代わりにオブジェクトインスタンスを直接格納することでスペース効率が向上します。プロセッサのキャッシュメモリがどのように機能するかを理解していれば、コンテナ内のオブジェクトインスタンスを "インライン"で格納することがどのように実際のパフォーマンス上の利点をもたらすかを理解することは難しくありません。

含まタイプ又は容器の使用パターンについての仮定を行うことなく、デフォルト容器はstd::vector<T>(としないstd::vector<T*>)であるべきです。そのデフォルトの選択肢から、その他のタイプの構造のパフォーマンスプロファイルから使用パターンがどのように恩恵を受けるかを見ることができれば、ベクトル以外のものを使用します。同様に、ポインターの間接指定が必要な場合はオブジェクトへのポインターをコンテナーストアに格納するか、パフォーマンスの観点からその価値があるようです。格納された型がコピーコンストラクタブルでない場合は間接指定が必要であり、コンテナがそのオブジェクトを「所有していない」場合にも必要です。