接口缩容
? ? ? ? 在VS编译器的模式下,类似于erase和insert接口的函数通常会进行缩容,因此,insert和erase行参中的迭代器可能会失效。下图中以erase为例:
????????代码如下:
#include <iostream>
#include <vector>
#include <string>
using namespace std;
int main()
{
?? ?vector<int> v = { 1,2,3,4,5,6 };
?? ?vector<int>::iterator it = v.begin();
?? ?while (it != v.end()) //vs做出了调整,不让我们做出访问,因为此时的迭代器已经失效
?? ?{
?? ??? ?if (*it % 2 == 0)
?? ??? ?{
?? ??? ??? ?v.erase(it);
?? ??? ??? ?//正确做法如下,用返回值的形式直接指向新空间中特定的位置
?? ??? ??? ?//it = v.erase(it);
?? ??? ?}
?? ??? ?else
?? ??? ?{
?? ??? ??? ?it++;
?? ??? ?}
?? ?}
?? ?for (auto e : v)
?? ?{
?? ??? ?cout << e << " ?";
?? ?}
?? ?return 0;
}
? ? ? ? 总的来说迭代器失效的本质是原本的迭代指向指向的不是数据的位置了。
模板string
? ? ? ? 当容器戎装string类时,在使用中要注意string类中构造函数的使用。当容器戎装string使用拷贝或赋值等其它会发生string构造时,一定要注意析构函数会释放掉原有空间内的所有数据的情况
//当模拟实现vector容器接口string类型时的reserve接口的情况
void reserve(size_t n)
{
?? ?if (n > capacity())
?? ?{
?? ??? ?size_t old = size();
?? ??? ?T* tmp = new T[n];
?? ??? ?if (_start)
?? ??? ?{
?? ??? ??? ?//memcpy(tmp, _start, old * sizeof(T));拷贝错误,string内部实现构造函数时将会刷新原有的数据
?? ??? ??? ?for (size_t i = 0; i < old; i++)
?? ??? ??? ?{
?? ??? ??? ??? ?tmp[i] = _start[i];
?? ??? ??? ?}?? ??? ??? ?delete[] _start;
?? ??? ?}?? ??? ?_start = tmp;
?? ??? ?_finish = _start + old;
?? ??? ?_endofstorage = _start + n;
?? ?}
}