注:关于迭代器失效部分的总结,仅代表个人看法,书上只是说插入和擦除操作可能会使迭代器失效,但具 体什么情况下会失效并没有作说明。此问题将留待日后研究STL(Standard Template Library)再解决
1.迭代器的范围
eg:
vector<int> vec(10);
则迭代器的范围:
[ vec.begin(),vec.end());
*迭代器end绝对不能位于begin之前
2.容器定义的类型别名
解析:
value_type,reference等,使程序员无需知道容器元素的真正类型就能使用它
3.顺序容器的操作
*添加元素到末端
以vector为例
原型:
void push_back (const value_type& val);
eg:
vector<int> vec;
vec.push_back(1);
*添加元素到前端
以list为例
原型:
void push_front( const T& value );
eg:
list<int> lst;
lst.push_front(1);
*在指定位置添加元素
以list为例
原型:
single element :
iterator insert (iterator position, const value_type& val);
fill :
void insert (iterator position, size_type n, const value_type& val);
range :
template <class InputIterator>
void insert (iterator position, InputIterator first, InputIterator last);
解析:
position : iterator指示的位置之前将被插入
val : 被插入元素的值
n : 被插入元素的个数
first, last : 左闭区间范围的元素将被插入
返回值iterator: 指向插入元素后的位置
eg:
int arr[]={1,2,3,4,5};
list<int> lst;
list<int> lst1;
list<int> lst2;
list<int>::iterator it=lst.insert(lst.begin(),1);//lst内的元素为1
cout<<*it<<endl;//输出1,说明insert返回的是插入1后的位置
lst1.insert(lst1.end(),3,1);//lst1内的元素为1,1,1
lst2.insert(lst2.end(),arr+1,arr+3);//lst内的元素为2,3
4.使迭代器失效的操作
*删除
以vector的erase()为例:
原型:
iterator erase (iterator position);
iterator erase (iterator first, iterator last)
注:erase操作不会改变容器的容量,但会改变容器的大小。
擦除迭代器后面的元素,迭代器不会失效
擦除迭代器前面的元素,迭代器则会失效
eg:
int arr[]={1,2,3,4,5};
vector<int> vec(arr,arr+5);
vector<int>::iterator it=vec.begin()+2;
cout<<*it<<endl;
vec.erase(vec.end()-1);//擦除迭代器后面的元素
cout<<*it<<endl;//ok
vec.erase(vec.begin());//擦除迭代器前面的元素
cout<<*it<<endl;//error
*添加
以vector为例:
注:当容器容量不足时,将引起重新分配空间,此时,任何形式的插入都会导致迭代器失效
当容器容量充足时,在迭代器后面插入,迭代器指向的内容部不变,在迭代器前面插入,迭代器指向的内容改变。
eg:
int arr[]={1,2,3,4,5};
vector<int> vec(arr,arr+5);
vec.reserve(10);//重新指定容量为大小10
vector<int>::iterator it=vec.begin()+2;
cout<<*it<<endl;//输出3
vec.insert(vec.end(),6);//在it迭代器后插入,且容量充足
cout<<*it<<endl; //ok,it迭代器依然有效,输出3
vec.insert(vec.begin(),7);//在it迭代器前插入,且容量充足
cout<<*it<<endl; //ok,it迭代器指向的内容已改变,输出2