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;
}