STL源码剖析1--- vector的底层实现 insert函数的实现

STL源码剖析1 — vector的底层实现 insert函数的实现
转载请标明 原创:东篱_

一、说明

自己实现了 insert函数,
以及insert函数调用的部分子函数 __fill_n、__backCopy

其他部分参考博客 水目沾
和《STL源码剖析》

全部实现,请移步我的GitHub MissStrickland

二、insert函数缺点:
不能正确实现原vector尾部的插入,其他都可以。
原vector尾部的插入,结果如下:
每次都是在原vector的固定末尾位置插入新元素,并将之前插入的元素向后挪了挪。

三、代码
1、关键代码:
1.1、insert 函数

//插入 在值为value的一个元素到position的位置上
	void insert(iterator position, const T& value){
		insert(position, 1, value);
	}

	//在position位置之后,插入n的值为value的元素
	void insert(iterator position, size_type n, const T& value){
		if (n == 0)return;

		if ((end_of_storage - finish) >= n){//备用空间够插入n个新元素
			T x_copy = value;
			const  size_type size_from_position_to_end = finish - position;

			iterator old_finish = finish;
			if (size_from_position_to_end > n){
				__copy(finish - n, finish, finish);
				finish += n;
				__backCopy(position, old_finish - n, old_finish);
				__fill(position, position + n, x_copy);
			}
			else{
				__fill_n(finish, n - size_from_position_to_end, x_copy);
				finish += n - size_from_position_to_end;
				__copy(position, old_finish, finish);
				finish += size_from_position_to_end;
				__fill(position, old_finish, x_copy);
			}
		}
		else{
			//重新申请空间
			const size_type old_size = size();
			size_type _max = 0;
			if (old_size > n) _max = old_size;
			else _max = n;
			const size_type len = old_size + _max;
			iterator new_start = (iterator)malloc(len * sizeof(T));
			iterator new_finish = new_start;
			//内存的分配要有原子性,即:要么全部成功,要么全部失败。
			try{
				new_finish = __copy(begin(), position, new_start);//1.将原内容 至position的所有元素(不包含position) 拷贝到新的vector
				new_finish = __fill_n(new_finish, n, value);//2.将position位置到后面的n个元素都填充为value
				new_finish = __copy(position, end(), new_finish);//3.拷贝从 position位置到end()位置的原vector的所有剩余元素
			}
			catch (...)//如果失败了
			{
				destroy(new_start, new_finish);
				free(new_start);//删除申请到的内存
				new_start = new_finish = NULL;
				throw;        //抛出异常
			}
			//析构并释放原vector
			destroy(begin(), end());
			//删除内存
			free(start);
			//调整迭代器,指向新的vector
			start = new_start;
			finish = new_finish;
			end_of_storage = new_start + len;
		}
	}

1.2、insert 中调用的一些子函数:

//将first到last迭代器之间(first,last)的元素拷贝到_start开始的内存中, 并返回 指向 拷贝完所有数据之后最后一个数据的下一个位置的指针
	iterator __copy(iterator first, iterator last, iterator _start){
		while (first < last){
			*_start++ = *first++;
		}
		return _start;
	}

	iterator __fill(iterator first, iterator last, const T& value){
		while (first < last){
			*first++ = value;
		}
		return first;
	}

	//自己写的 从迭代器first开始填充n个值为value的元素
	iterator __fill_n(iterator first, size_type n, const T& value){
		while (n--){
			*first++ = value;
		}
		return first;
	}


	//自己写的  将从 [first,last)所有元素 一一依次后移, 最后的一个元素移到end的位置
	void __backCopy(iterator first, iterator last, iterator end){
		while (first <= last){
			*end-- = *last--;
		}
	}

2、测试代码:

#include"myVector.h"

void disp(const myVector<int> &v){
	for (myVector<int>::iterator it = v.begin(); it != v.end(); ++it){
		cout << *it << " ";
	}
	cout << endl;
}
void test(){
	cout << "test--------" << endl;
	myVector<int> v(100);
	v.push_back(10);
	v.push_back(9);
	v.push_back(8);
	v.push_back(7);
	v.push_back(6);
	v.push_back(5);
	for (int i = 0; i < v.size(); ++i)
		cout << v[i] << " ";
	cout << endl;

	myVector<int>::iterator it;
	for (it = v.begin(); it != v.end(); ++it){
		cout << *it << " ";
	}
	cout << endl;
	cout << "size: " << v.size() << endl;
}

void test1(){
	cout << "test1--------" << endl;
	myVector<int> v(100);
	v.push_back(10);
	v.push_back(9);
	v.push_back(8);
	v.push_back(7);
	v.push_back(6);
	v.push_back(5);

	myVector<int>::iterator it = v.begin() + 3;//vector的第三个元素之后插入多个相同的元素

	v.insert(it, 3, 300); disp(v);
	v.insert(it, 4, 500); disp(v);
	v.insert(it, 2, 200); disp(v);
	v.insert(it, 2, 20); disp(v);
	v.insert(it, 3, 30); disp(v);
	v.insert(it, 4, 40); disp(v);
}



void test2(){
	cout << "test2--------" << endl;
	myVector<int> v(100);
	v.push_back(10);
	v.push_back(9);
	v.push_back(8);
	v.push_back(7);
	v.push_back(6);
	v.push_back(5);

	myVector<int>::iterator it = v.begin();//vector的头部插入单个元素

	v.insert(it, 300); disp(v);
	v.insert(it, 500); disp(v);
	v.insert(it, 200); disp(v);
	v.insert(it, 20); disp(v);
	v.insert(it, 30); disp(v);
	v.insert(it, 40); disp(v);

}
int main(){
	test();
	test1();
	test2();

	return 0;
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值