vector模拟实现【C++】-insert

时间:2024-07-07 10:06:31
	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,就扩2reserve(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的返回值要是指向新插入的数据的迭代器