5

の前または後に削除する必要がありeraseます。私の理解では、どちらも問題ありません。それが正しいか?

さらに、消去中に要素を削除したくない場合はありますか? あるに違いないと私は信じています。さもなければ、erase喜んで責任を取ります。

std::vector<foo*> bar;
...
for (vector<foo*>::iterator itr = bar.begin(); itr != bar.end(); itr++)
{
   delete (*itr);  //before OR
   bar.erase(itr);
   delete (*itr);  //after???
}
4

5 に答える 5

10

「itr」は次のように使用する必要があります。

for (vector<foo*>::iterator itr = bar.begin(); itr != bar.end(); )
{
   delete (*itr);
   itr = bar.erase(itr);
}

ただし、最初にすべての要素を削除してから、ベクターをクリアすることをお勧めします。

for (vector<foo*>::iterator itr = bar.begin(); itr != bar.end(); ++itr)
   delete (*itr);
bar.clear();
于 2010-09-17T06:51:01.010 に答える
4

イテレータを使用して要素を消去すると、イテレータが無効になります。消去する前にアイテムを削除する必要があります。

また、次のループ反復には、erase からの戻り値を使用する必要があります。

于 2010-09-17T06:28:27.857 に答える
3

さらに、消去中に要素を削除したくない場合はありますか?

他の誰かが指しているオブジェクトを必要としているかどうか、ベクトルはどうやって知ることができるでしょうか? ポインティがヒープに格納されていることをどのように知ることができますか? ベクター内の静的オブジェクトまたは自動オブジェクトへのポインター、またはダングリング ポインターを使用することは完全に可能です。

C++0x では、ベクトルが指す先を所有する必要があることを表現できます。

std::vector<std::unique_ptr<foo>> vec;

これで、手動で何かを削除する必要がなくなりました。一意のポインターを消去すると、それぞれのポインターも削除されます。最新の C++ では、ネイティブ ポインターのコンテナーは非常にまれです。

C++0x コンパイラがない場合は、代わりにstd::vector<boost::shared_ptr<foo> >orを使用できますboost::ptr_vector<foo>。最新のコンパイラshared_ptrは、std::tr1またはstd名前空間でも提供します#include <memory>

于 2010-09-17T08:42:18.853 に答える
2

最初の要素を消去すると配列全体が前方にシフトするというベクトルの性質により、この操作を減らすには、次のことを試してください。

std::vector<foo*> v1;
//...
while(!v1.empty())
{
    delete v1.back();
    v1.pop_back( );
}

ちなみに、このメソッドはイテレータを無効にしません(消去されたアイテムのみ)

于 2010-09-17T07:07:07.933 に答える
1

を実行すると、イテレータeraseが無効になります。vectorそのため、*iter未定義の動作が呼び出されます。deleteしたがって、 の後にを実行する必要がありますeraseeraseまた、それを繰り返しながらa から要素を取得することはできませんvector(同じ理由で、無効にiterなるのでiter++無効になります)。この場合erase、ループ内から呼び出しを削除しclear、ループ外でベクトルを実行できます。

于 2010-09-17T06:33:49.797 に答える