《STL源码剖析》chapter4 序列式容器之vector

vector概述

vectorarry非常相似,不同之处在于array是静态空间,一旦大小设定就不能改变;而vector是动态空间,随着元素的加入,它的内部机制会自行扩充空间以容纳新元素。

vector的迭代器

vector维护的是一个连续线性空间,所以使用普通指针就可以作为vector的迭代器。所以vectro提供的是Random Access Iterator

template<class T,class Alloc=alloc>
class vector{
    public:
        typedef T           value_type;
        typedef value_type* iterator;       //vector的迭代器
};
vector的数据结构

vector所采用的数据结构非常简单:线性连续空间。它以两个迭代器startfinish表示目前使用空间的头尾,用end_of_storage指向整块连续空间的尾段.

template<class T,class Alloc=alloc>
class vector{
    //...
    protected:
        iterator start;         //表示目前使用空间的头
        iterator finish;        //表示目前使用空间的尾
        iterator end_of_storage;//表示目前可用空间的尾
};
vector的构造与内存管理

当备用空间不足时,vector采用二倍扩充的方式重新配置,即申请两倍大的新空间移动数据释放原空间。采用这种方式,可以使得push_back()操作时间复杂度的平摊代价为O(1), 其代码如下所示:

template<class T,class Alloc>
void vector<T,Alloc>::insert_aux(iterator position,const T& x){
    if(finish!=end_of_storage){
        //还有备用空间
        //在备用空间起始处构造一个元素,并以vector最优一个元素值为其初值
        wj::construct(finish,*(finish-1));
        //调整水位
        ++finish;
        T x_copy=x;
        //将positionk和其后面元素的位置往后挪
        std::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;
        iterator new_start=data_allocator::allocate(len);
        iterator new_finish=new_start;
        try{
            //复制前半段内容到新vector
            new_finish=std::uninitialized_copy(start,position,new_start);
            //为新元素设定初值x
            wj::construct(new_finish,x);
            ++new_finish;
            //复制后半段内容到新vector
            new_finish=std::uninitialized_copy(position,finish,new_finish);
        }
        catch(...){
            //处理异常
            wj::destory(new_start,new_finish);
            data_allocator::deallocate(new_start,len);
            throw;
        }
        //析构并释放原vector
        wj::destory(begin(),end());
        deallocate();
        //调整迭代器,指向新vector
        start=new_start;
        finish=new_finish;
        end_of_storage=new_start+len;
    }
}
最后

本节中涉及的代码及本人实现的toy级别的vector可以参考github.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值