STL之vector
vector的数据以及操作方式,与array非常相似。但是array是静态空间,一旦配置了就不能改变;而vector是动态空间,随着元素的加入,它的内部机制会自行扩充空间以容纳新元素,因此vector的运用对于内存的合理使用与运用的灵活性有很大的帮助。
vector的迭代器
vector维护的是一个连续线性空间,所以不论其元素为何,普通指针都可以作为vector的迭代器而满足所有的要求,因为vector迭代器所需要的操作行为,如operator*,operator->,operator++,operator–,operator+,operator+,operator+=,operator-=等,普通指针天生就具备。vector支持随机存取,而普通指针正有着这样的能力,所以,vector提供的是Random Access Iterator.
template<class T,class Alloc=alloc>
class vector{
public:
typedef T value_type;
typedef value_type* iterator; //普通指针
}
根据以上定义,如果客户端的代码写成这样
vector<int>::iterator ivite;
vector<shape>::iterator svite;
ivite的型别是int * ,svite的型别是shape*.
vector的数据结构
vector所采用的数据结构非常简单:线性连续空间。它以两个迭代器start和finish分别指向配置的来的连续空间中目前已被使用的范围,并以迭代器end_of_storage指向整个块连续空间的尾端:
template<class T,class Alloc=alloc>
class vector{
.....
protected:
iterator start;
iterator finish;
iterator end_of_storage;
};
为了 降低空间配置时的成本,vector实际配置的大小可能比客户需求的大一些,以备将来可能扩充。
运用这三个迭代器,便可轻易的提供首尾标识,大小容量,空容器的判断,标注([])运算子,最前端元素值,最后端元素值等方法.
template<class T,class Alloc=alloc>
class vector{
....
public:
iterator begin(){return start;}
iterator end(){return finish;}
size_type size()const {return size_type(end()-begin());}
size_type capacity()const{reutrn size_type(end_of_storage-begin());}
bool empty()const {return begin()==end();}
reference opearator[](size_type n){return *(begin()+n);}
reference front(){return *begin();}
reference back(){return *(end()-1);}
};
vector的元素操作:pop_back,erase,clear,insert
void pop_back(){
--finish;
destroy(finish);
}
//清除[first,last)中的所有元素
iterator erase(iterator first,iterator last){
iterator i=copy(last,finish,first);
destroy(i,finish);
finish=finish-(last-first);
return first;
}
//清除某位置上的元素
iterator erase(iterator position){
if(position+1!=end()){
copy(position+1,finish,position);
--finish;
destroy(finish);
return position;
}
}
void clear(){erase(begin(),end());}
insert()函数:
//从position开始,插入n个元素,元素初值为x
template<class T,class Alloc=alloc>
void vector<T,Alloc>::insert(iterator position,size_type n,const T &x){
if(n!=0){
if(size_type(end_of_storage-finish)>=n){//备用空间大于等于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);
finish+=n;
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);
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);
//再将剩下的元素插入
new_finish=uninitialized_copy(position,finish,new_finish);
}
//释放久的vector;
destroy(start,finish);
deallocate();
start=new_start;
finish=new_finish;
end_of_storage=new_start+len;
}
}
}
下图展示了insert(position,n,x)的操作