2009-09-05 13 views
12

私は、STLコンテナ(ベクトル、リスト、マップなど)がどのように値を格納するかについて常に混乱してきました。彼らは私が渡した値への参照を保存しているのですか、あるいはコピー/コピーして+値を保存していますか?STL:参照または値を格納しますか?

例えば、

int i; 
vector<int> vec; 
vec.push_back(i); 
// does &(vec[0]) == &i; 

class abc; 
abc inst; 
vector<abc> vec; 
vec.push_back(inst); 
// does &(vec[0]) == &inst; 

おかげで

+5

答えをテストする作業コードが好きです(コメントを条件付きにするための小さな変更)。それを実行し、参照してください!私は彼らがコピーを作って保存するのはかなり確信しています。 –

答えて

18

STLコンテナはあなたが合格し、店舗の値-構造をコピーします。あなたは、コンテナ内のオブジェクトを格納する場合をコピーせずに、コンテナ内のオブジェクトへのポインタを格納することをお勧めします。

class abc; 
abc inst; 
vector<abc *> vec; 
vec.push_back(&inst); 

これは、無効なスタックフレーム上の変数への参照を誤って格納しないように、コンテナクラスを実装する最も論理的な方法です。考えてみましょう:

class Widget { 
public: 
    void AddToVector(int i) { 
     v.push_back(i); 
    } 
private: 
    vector<int> v; 
}; 

あなたはそれが定義されたメソッドから復帰した後のローカル変数のメモリ位置を参照することになるようiへの参照を格納することは危険です。

+5

C++で参照を格納するコンテナを作成することはできません。コンテナに渡される型引数は、代入可能でなければなりません。参照は割り当て可能ではなく、オブジェクトで初期化されますが、構築後に別のオブジェクトを参照するように割り当てることはできません。したがって、参照型は、コンテナ内で使用される型の要件を満たしません。同じセマンティクス(またはそれが得られるのと同じくらい)を望むなら、参照ラッパー(boost :: ref/boost :: cref)を提供する必要があります。 –

+3

@dribeas:この答えは_why not_を説明しています。実装。 – MSalters

4

あなたのタイプによって異なります。それが単純な値の型で、値をコピーするのが安ければ、値を格納するのがおそらく答えです。一方、参照型やコピーが高価な場合は、スマートポインタ(auto_ptrではなく、特別なコピーセマンティクスによってコンテナに格納されないため)を格納する方がよいでしょう。プレーンポインタを使用すると、メモリリークや解放されたメモリへのアクセスが危険にさらされますが、参照を使用すると、後者を危険にさらします。スマートポインタは、両方を回避します。

+2

メモリを扱うためにコンテナ内でスマートポインタを使用する場合は+1してください。 Boost Pointer Containerのようなライブラリを使用してリソースの割り当て解除を処理する別の方法もあります。 –

+5

これはOPが求めていることではありません。彼はコンテナクラスがそれがコンテナに置かれたときに値をコピーするかどうかを知りたい。その答えは、はい、そうです。そのため、問題の特定のタイプがコピーするのに費用がかかる場合は、ポインタを格納することが有効なことがあります。 –

+2

あなたが何をしているのか分かっていて、あなた自身の後できれいにするならば、裸のポインタを格納することはまったく問題ありません。 –

関連する問題