1

OK、私は何かを一度だけクリアしたいと思います。次のような法線ベクトルがある場合:

std::vector<Object*> coll;

そして私はその要素を調べたいと思います、私はそれについて行くための3つの方法を知っています:

1.int次のようなインデックスを使用します。for(int i = 0; i < coll.size(); ++i)

2.インデックスを使用しtype_tます。1と同じです。for(size_t i = 0; i < coll.size(); ++i)

1と2の両方の要素にアクセスするには:coll[i]

また

3.const_iteratorのように、を使用します。

std::vector<Object*>::const_iterator i;
for(i = coll.begin(); i != coll.end(); ++i)
       // stuff

で要素にアクセスし*itます。

私は3番目の方法が最も失敗のない方法であることに気づきました(そして聞いた)が、ベクトルの割り当てを解除することになると、それは非常に不快ですconst_iterator。その値を失い、ループを続行できなくなります。delete (*it)coll.erase(it)for

これを行うための提案された/良い方法は何ですか?

4

4 に答える 4

3

最初の 2 つのアプローチはどちらも完全に正しいわけではありません。正しいインデックスの種類は

std::vector<Object*>::size_type

これはsize()が返すものであり、operator[]が取るものです。

イテレータを使用するアプローチは慣用的なものです。あなたが書いた

const_iterator を使用する場合、割り当て解除の前に delete (*it) や coll.erase(it) などを実行すると、イテレーターの値が失われ、for ループを続行できなくなります。

これは正しくありません。のようなもので

// ..
std::vector<int *>::const_iterator it, end = v.end();
for ( it = v.begin(); it != end; ++it ) {
    delete *it;
}

iterator を無効にしませんitdeleteイテレータが指すものを呼び出すだけです。したがって、 の後にイテレータを安全に進めることができますdelete

于 2012-09-07T07:02:01.193 に答える
1

#31 つはより一般的なもので、コードをより柔軟にします。
ある時点で、標準ライブラリ コンテナーを からstd::vector他のコンテナーに変更する必要がある#3場合は、他のコンテナーのいずれでもそのまま使用できます (またはの代わりに を使用することに注意してください!=<>) 。

于 2012-09-07T07:02:25.473 に答える
1

size_t は、基本的にオブジェクトの最大サイズを保持するのに十分な大きさの型であると定義されているため、配列へのインデックス付けに使用する一般的な正しい型です。実際にはメモリ範囲のサイズとして定義されていますが、十分な大きさになることがわかるように配列インデックスを保持するのに最適な型でもあります。

64 ビット システムでは、数百 GB のメモリを満たす配列を持つことができますが、int は最大 20 億程度の数値しか保持できませんが、size_t は、システムが処理できる配列にインデックスを付けるのに適切な型である必要があります。

于 2012-09-07T07:08:05.997 に答える
1

あなたが書いた:

...または解放する前に coll.erase(it) を実行すると、イテレータが値を失い、for ループを続行できなくなります...

vector::eraseコレクション内の次の有効な要素への反復子を返します。したがって、次のように書くことができます。

std::vector<Object*>::const_iterator i;
for(i = coll.begin(); i != coll.end(); )
{
  i = coll.erase(i);
}

その場合、インクリメントしてはならないことに注意してくださいi( i++)。

于 2012-09-07T07:10:22.607 に答える