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

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章