-3

だから私はこの質問を見ました。これは基本的に、参照とイテレータが一緒に無効になることを示しています。

特定のケースでイテレータが無効になる理由はわかりますが、参照が無効になるのはなぜですか?

実用的な観点からは、なぜこれが必要なのかわかりません。

それは単なる設計上の決定でしたか、それとも実際的な理由がありますか?

編集:明確にするために、基になる構造を理解している限り、再割り当てする必要があるのはデータへのポインターにすぎません(データ(およびその参照)はそのまま残ります)。右?

いくつかのテスト コード:

#include <vector>
#include <iostream>
using namespace std;

int main()
{
    vector<string> yourVect;
    yourVect.push_back("def");
    vector<string>::iterator iter = yourVect.begin();
    const string& ref = *iter;
    yourVect.insert(yourVect.begin(), "abc");
    cout << ref << endl; // !! --- doesn't work - why ?? --- !!
    cout << *iter << endl; // obviously doesn't work
}
4

1 に答える 1

4

ベクトルの先頭に文字列を挿入すると、すべてのデータを1つの場所の前方に移動する必要があり、の容量vectorが使い果たされた場合は、vectorを再割り当てする必要があります。

したがって、参照はせいぜい別のデータを参照し、最悪の場合は無効なメモリ位置を参照します。ベクトルが再割り当てされると、新しいメモリブロックが割り当てられ、古いデータが新しいブロックと古いブロックに1コピーされます。割り当てが解除されます。すべての古い参照は古いブロック内のメモリ位置を指しているため、それらはすべて無効になります。

保証は「最悪の場合」に関するものです。そのため、insert操作後も参照が有効であることが保証されていません。または、別の言い方をすれば、ベクトルに挿入するとイテレータと参照が無効になる場合があります。

また、参照とイテレータの間でこの動作に実質的な違いがあると思う理由がわかりません-vectorイテレータは通常、参照された位置への単なるポインタであるためvector(多くの場合、実装定義のクラス内に隠されています)、多かれ少なかれ参照と同じ。


  1. C ++ 11のIIRCは、実際には「移動」されます(のようにstd::move)。これは、古い参照がその時点で割り当て解除されたメモリを指し続けるという事実を変更しません。
于 2013-02-23T21:20:52.680 に答える