iterator insert(iterator pos, const T& val)
{
assert(pos <= _finish); 防止插入的位置是 越界的
if (_finish == _end_of_storage) 如果容量满了
{
记录一下扩容前的pos与start的相对位置
因为扩容的话会导致pos迭代器失效
size_t n = pos-_start;
if (capacity() == 0) 如果容量为0
reserve(2);
else 容量不为0,就扩2倍
reserve(capacity() * 2);
更新pos
pos = _start + n;
}
iterator it = end()-1;
把pos及其之后的数据向后挪动一位
while (it >= pos)
{
*(it + 1) = *it;
it--;
}
_finish++;
*pos = val;插入数据
返回指向新插入的数据的迭代器
用于处理迭代器失效问题
return pos-1;
}
为什么扩容会导致pos迭代器失效?
因为扩容之后原来的空间被释放了
又因为使用的扩容方式是reserve所以那3个成员变量的值扩容后可以指向正确的位置。
但是pos如果不更新的话,就还是指向被释放的空间,就成了野指针了。
更新方法也很简单,保存扩容之前的pos与start的相对距离n,扩容之后再让pos=_start+n就可以了。
为什么要返回pos-1?
这是stl库里面处理迭代器失效的方法之一
因为我们在使用stl库里面的insert函数的时候,是不知道什么时候会扩容的【每个平台实现的vector是不同的
】
只能默认使用了之后传进去pos,在调用一次insert之后就失效了,失效的迭代器是不能使用的。
所以如果还要用pos就要把它更新一下,stl库里提供的更新方式就是:
==让pos接收insert的返回值。【pos是传值调用,形参改变不影响实参
】==并且规定insert的返回值要是指向新插入的数据的迭代器