c++ 容器迭代器的问题!!
关于容器swap()函数的问题 这个事交换两个容器的元素 我做了一下验证
int a[5] = {0,5,6,9,8};
vector<int> vec1(a,a+5);
vector<int>::iterator it1 = vec1.begin()+2;
int b[8] = {6,9,12,1,15,10,20,100};
vector<int> vec2(b,b+8);
vector<int>::iterator it2 = vec2.begin() + 2;
cout<<"两个容器的首地址"<<vec1.begin()<<" "<<vec2.begin()<<endl;
cout<<"交换前两个首数";
cout<<vec1[0]<<" "<<vec2[0]<<endl<<endl;
cout<<"交换前两个迭代器指向的元素:";
cout<<*it1<<" "<<*it2<<endl;
cout<<it1<<" "<<&vec1[2]<<" "<<it2<<" "<<&vec2[2]<<endl;//这个是所指地址
vec1.swap(vec2);
cout<<"两个容器的首地址"<<vec1.begin()<<" "<<vec2.begin()<<endl;
cout<<"交换后两个首数:";
cout<<vec1[0]<<" "<<vec2[0]<<endl<<endl;
cout<<"交换后两个迭代器指向的元素:";
cout<<*it1<<" "<<*it2<<endl;
cout<<it1<<" "<<&vec1[2]<<" "<<it2<<" "<<&vec2[2]<<endl;
//由 上可以看出,虽然两个容器交换了,但是迭代器并没有失效
输出:
两个容器的首地址007E3270 007E32B8
交换前两个首数0 6
交换前两个迭代器指向的元素:6 12
007E3278 007E3278 007E32C0 007E32C0
两个容器的首地址007E32B8 007E3270
交换后两个首数:6 0
交换后两个迭代器指向的元素:6 12
007E3278 007E32C0 007E32C0 007E3278
Press any key to continue
问题来了
1.虽说两个迭代器指向的元素并没有变,但是从输出看他们指向的地址也没变吧 那么是靠什么识别 原指向元素呢?
2.两个容器用swap交换 实际不是其内元素简单的交换 而是两个容器交换,根本是地址也交换了,那么交换后在输出it1 和 it2 的地址怎么和没交换前的地址一样呢?
[解决办法]
首先,vector内部是维护一个动态数组,大概样子是这样:
class vector
{
T* begin;
T* finish;
T* capacity;
};
vector::iterator虽说不一定是用指针实现,但是一定保存了数组中元素的真实内存地址(其实也不是一定,实现也可以保存begin和偏移量,但这么做明显太复杂,实际中都是直接保存元素地址的)。
vector整个swap的时候,其实交换的是双方begin, finish, capacity这三个指针的值。在这个过程中,所有从该vector创建的iterator本身都不会发生任何改变(打个比方就是你换一个手机号,那些存了你以前手机号的人手头的电话号码并不会随之发生改变,除非你告诉他们)。因为iterator没有改变,所以你打印iterator本身的地址时,得到的仍旧是原来的值。另外,动态数组本身并没有被销毁,只是改变了所属。所以实际两个vector中所有元素的物理地址都没有改变,iterator指向的依然是原来的元素。
[解决办法]
std::vector::swap
<vector>
void swap (vector& x);
Swap content
Exchanges the content of the container by the content of x, which is another vector object of the same type. Sizes may differ.
After the call to this member function, the elements in this container are those which were in x before the call, and the elements of x are those which were in this. All iterators, references and pointers remain valid for the swapped objects.
[解决办法]
[解决办法]