vector源码以及实例

本文深入探讨了C++中的vector容器,详细解析了其内部源码,并通过一个实际例子展示了vector的使用方法和功能,帮助读者理解vector在程序设计中的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/*
vector与array数组比较类似 但是array是静态空间,一旦配置了空间就不能够再改变
vecotr是动态空间,随着元素的加入,它的内部机制就会自行扩充空间来容纳新的元素
//下面将真是vector函数的具体实现
//vector是一个连续的线性空间
*/
//alloc是SGI的空间配置器
template <class T,Alloc=alloc>
class vector{
public:
	//vector的嵌套型别定义
	typedef T			value_type;
	typedef value_type* 		pointer;
	typedef value_type*		iterator;
	typedef value_type&		reference;
	typedef size_t			size_type;
	typedef ptrdiff_t		difference_type;
protected:
	//以下,simple_alloc是SGI STL的空间配置 器  专属配置器 每次配置一个元素大小
	typedef simple_alloc<value_type,Alloc>data_allocator;
	iterator 		start;//表示目前使用空间的头
	iterator 		finish;//表示目前使用空间的尾
	iterator 		end_of_storage;//表示目前可用空间的尾
	void insert_aux(iterator position,const T&x);
	void deallocate(){
	if(start)//如果它不是空的
		data_allocator(start,end_of_storage-start);
	}
	void fill_initialize(size_type n,const T& value){
		start=allocate_and_fill(n,value);
		finish=start+n;
		end_of_storage=finish;
	}
public:
	iterator begin(){return start;}
	iterator end(){return end;}
	size_type size() const {return size_type(end()-begin());}
	size_type capacity()const{
	return size_type(end_of_storage-begin());
	}
	bool empty()const{return begin()==end();}
	reference operator[](size_type n){return *(begin()+n);}
	vector():start(0),finish(0),end_of_storage(0){}
	vector(int n,const T& value){fill_initialize(n,value);}
	vector(long n,const T& value){fill_initialize(n,value);}
	explicit vector(size_type n){fill_initialize(n,T());}
	~vector(){
		destory(start,finish);
		deallocate();//这是vector的一个member function
	}
	reference front(){return *begin();}//第一个元素
	reference back(){return *(end()-1);}//最后一个元素
	void push_back(const T&x){//将元素插至最尾端
	if(finish!=end_of_storage){
		construct(finish,x);//全局函数
		++finish;
	}else
	insert_aux(end(),x);//成员函数

	}
	void pop_back(){//将最尾端的元素取出来
	--finish;
	destroy(finish);//全局函数
	}
	iterator erase(iterator position){//清除某个位置上的元素
	if(position+1!=end())
	copy(position+1,finish,position);//后续元素向前移动
	--finish;
	destory(finish);//全局函数
	return position;
	}
	void resize(size_type new_size,const T & x){
	if(new_size<size()){
		erase(begin()+new_size(),end());
	}else{
		insert(end(),new_size-size(),x);
	}
	void resize(size_type new_size){resize(new_size,T());}
	void clear(){erase(begin(),end());}
protected:
	//配置空间并填满内容
	iterator allocate_and_fill(size_type n,const T&x){
		iterator result=data_allocator::allocate(n);
			uninitialized_fill_n(result,n,x);//全局函数
			return result;
			
}
}
};

下面给出一个实例

#include<vector>
#include<iostream>
#include<algorithm>
using namespace std;
int main(){

	int i;
	vector<int>iv(2,9);//size=2;
	cout<<"size="<<iv.size()<<endl;
	cout<<"capacity="<<iv.capacity()<<endl;
	
	iv.push_back(1);
	cout<<"size="<<iv.size()<<endl;
	cout<<"capacity="<<iv.capacity()<<endl;
	iv.push_back(2);		
	cout<<"size="<<iv.size()<<endl;
	cout<<"capacity="<<iv.capacity()<<endl;
	iv.push_back(3);
	cout<<"size="<<iv.size()<<endl;
	cout<<"capacity="<<iv.capacity()<<endl;
	iv.push_back(4);
	cout<<"size="<<iv.size()<<endl;
	cout<<"capacity="<<iv.capacity()<<endl;
	for(i=0;i<iv.size();++i)
		cout<<iv[i]<<' ';
	cout<<endl;
	iv.push_back(5);
	cout<<"size="<<iv.size()<<endl;
	cout<<"capacity="<<iv.capacity()<<endl;
	for(i=0;i<iv.size();++i)
		cout<<iv[i]<<' ';
	cout<<endl;
	iv.pop_back();
	iv.pop_back();	
	cout<<"size="<<iv.size()<<endl;
	cout<<"capacity="<<iv.capacity()<<endl;
	iv.pop_back();	
	cout<<"size="<<iv.size()<<endl;
	cout<<"capacity="<<iv.capacity()<<endl;
	
	vector<int>::iterator ivite=find(iv.begin(),iv.end(),1);
	if(ivite!=iv.end()) iv.erase(ivite);
	cout<<"size="<<iv.size()<<endl;//size=3;
	cout<<"capacity="<<iv.capacity()<<endl;
	for(i=0;i<iv.size();++i)
		cout<<iv[i]<<' ';
	cout<<endl;
	ivite=find(iv.begin(),iv.end(),2);
	if(ivite!=iv.end()) iv.insert(ivite,3,7);
	cout<<"size="<<iv.size()<<endl;
	cout<<"capacity="<<iv.capacity()<<endl;
	for(int i=0;i<iv.size();++i)
		cout<<iv[i]<<' ';
	cout<<endl;
	iv.clear();
	cout<<"size="<<iv.size()<<endl;//size=0
	cout<<"capacity="<<iv.capacity()<<endl;//size=8
}

下面是具体的函数实现

void vector<T,Alloc>::insert_aux(iterator position,const T& X){
	if(finish!=end_of_storage){//还有备用空间
		//在备用空间起始处构造一个元素 并以vector最后一个元素值为初值
	constructor(finish,*(finish-1));
	//调整水位
	++finish;
	T x_copy=X;
	copy_backward(position,finish-2,finish-1);
	*position=x_copy;
}else{//已经没有了备用空间
	const size_type old_size=size();
	const size_type len=old_size!=0?2*old_size:1;
	//以上配置原则:如果原大小为0,则配置1,
	//如果原大小不为0,则配置原来大小的两倍
	//前半段用来放置原数据,后半段用来放置新数据
	iterator new_start=data_allocator::allocate(len);//实际配置
	iterator new_finish=new start;
	try{
		//将原vector的内容拷贝到新的vector中去
		new_finish=uninitialized_copy(start,position,new_start);
		//为新元素设定初值
		construct(new_finish,x);
		//调整水位
		++new_finish;
		//将安插点的内容也拷贝过来
		new_finish=uninitialized_copy(position,finish,new_finish);
}catch(...){
		destory(new_start,new_finish);
		data_allocator::deallocate(new_start,len);
		throw;

}
		//析构并释放原vector
		destory(begin(),end());
		deallocate();
		//调整迭代器 指向新的vector
		start=new_start;
		finish=new_finish;
		end_of_storage=new_start+len;
	
}
}

template<class T,class Alloc>
void vector<T,Alloc>::insert(iterator position,size_type n,const T&x){
	if(n!=0){//要插入的元素不止是1
		if(size_type (end_of_storage-finish)>=n){
			//备用空间大于等于新增的元素个数
			T x_copy=x;
			//以下计算插入点后的现有元素个数
			const size_type elems_after=finish-position;
			iterator old_finish=finish;
			if(elems_after>n){
				//插入点之后的现有元素大于新增元素个数
				uninitialized_copy(finish-n,finish,finish);//类似于向后挪出n个位置给要插入的元素
				finish+=n;//将vector尾端标记后移
				copy_backward(position,old_finish-n,old_finish);
				fill(position,position+n,x_copy);//从插入点开始插入新值
}
else
{			//插入点之后的现有元素个数小于等于新增元素个数
			uninitialized_fill_n(finish,n-elems_after,x_copy);
			finish+=n-elems_after;
			uninitialized_copy(position,old_finish,finish)
			finish+=elems_after;
			fill(position,old_finish,x_copy);


}
}
		else{

			//备用空间小于"新增元素个数"(那就必须配置额外内存)
			//首先决定新长度;旧长度的两倍,或旧长度+新增元素个数
			const size_type old_size=size();
			const size_type len=old_size+max(old_size,n);
			//以下配置新的vector 
			iterator new_start =data_allocator::allocate(len);
			iterator new_finish=new_start;
			__STL_TRY{
				//以下先将旧的vector的插入点之前的元素复制到新空间
				new_finish=uninitialized_copy(start,position,new_start);
				//以下再将新增元素填到新空间
				new_finish=uninitialized_fill_n(new_finish,n,x);
				//一下再将旧vector的插入点之后的元素的插入到新空间
				new_finish=uninitialized_copy(position,finish,new_finish);

}
#ifdef __STL_USE_EXCEPTIONS
	catch(...){
		//如果异常发生,
		destroy(new_start,new_finish);
		data_allocator::deallocate(new_start,len);
		throw;
}
#endif/*__STL_USE_EXCEPTIONS*/
//以下清除并释放旧的vector
	destroy(start,finish);
	deallocate();
	//以下调整水位标记
	start=new_start;
	finish=new_finish;
	end_of_storage=new_start+len;

}
}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值