web-dev-qa-db-ja.com

std :: vectorはオブジェクトへのポインタのデストラクタを呼び出しますか?

可能性のある複製:
ベクター内のポインターの削除

std::vectorが破壊されると、各項目のデストラクターが呼び出されます。オブジェクトへのpointersのデストラクタを呼び出しますか?

vector<myclass*> stuff;

スタッフが破棄されると、スタッフ内のポインタが指す個々のオブジェクトが破棄されますか?

22
user2058002

番号。

どのようにstd::vectorは、ポイントされたオブジェクトを破棄する方法を知っているはずですか? deleteを使用する必要がありますか? delete[]free?他のいくつかの機能?指し示されたオブジェクトが実際に動的に割り当てられていること、またはそれが1つの真の所有者であり、それらを破棄する責任があることをどのように知っていると思いますか?

std::vectorが、ポイントされたオブジェクトの1つの真の所有者である場合は、std::unique_ptrを使用します。オブジェクトのクリーンアップを処理するために、カスタム削除機能を使用することもできます。

34
James McNellis

あなた自身が正しく言ったように、vectorはその要素のデストラクタを呼び出します。したがって、あなたの例では、ベクトルdoesは「ポインタのデストラクタ」を呼び出します。ただし、ポインタ型にはデストラクタがないことに注意してください。クラス型のみがデストラクタを持つことができます。そして、ポインタはクラスではありません。したがって、std::vectorが疑似デストラクター呼び出し構文をベクターに格納されているポインターオブジェクトに適用すると言うのがより正確です。何もしない、つまり何もしないポインタ型の場合。

これは、質問の2番目の部分にも答えます:ポインターが指すmyclassオブジェクトが破棄されるかどうか。いいえ、破壊されません。

また、「ポインタでデストラクタを呼び出す」(質問の最初の部分)は、「指摘されたオブジェクトを破壊する」(質問の2番目の部分)と同じことをどういうわけか信じているようです。実際には、これらは完全に異なる2つの無関係なものです。

前者から後者へのリンクを作成するには、つまりベクターが指定されたオブジェクトを破壊するようにするには、通常の生のmyclass *ポインターではなく、ある種の「スマートポインター」からベクターを構築する必要があります。ベクトルは自動的に「スマートポインタ」のデストラクタを呼び出し、次にこれらのデストラクタがポイントされたオブジェクトを破棄します。この「リンク」は、「スマートポインタの」デストラクタ内で明示的にのみ実装できます。そのため、通常の生のポインタはここでは役立ちません。

15
AnT

番号;自動オブジェクトへのポインタを保存するとどうなるでしょうか?

vector<T*> v;
T tinst;
v.Push_back(&tinst);

ベクトルがポインターが指すオブジェクトのデストラクターを呼び出す場合、自動オブジェクトは2回破壊されます。1回目はスコープ外になったとき、もう1回はベクターがスコープ外になったときです。また、それらがdeleteとの割り当て解除が想定されていない場合はどうなりますか?すべての状況で適切に動作する方法はありません。

オブジェクトがすべて動的に割り当てられている場合、deleteで割り当てられている場合は、ベクターとnew各ポインターを手動で反復する必要があります。別の方法として、スマートポインターのベクトルを作成することもできますwillポインターが指すオブジェクトの割り当てを解除します。

vector<shared_ptr<T>> v;
v.Push_back(new T);
5
Seth Carnegie