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