STL源码剖析——vector

vector结构体:

template <class T, class Alloc = alloc>
class vector {
public:
    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:
    typedef simple_alloc<value_type, Alloc> data_allocator;
    iterator start;             //目前使用空间头
    iterator finish;            //目前使用空间尾
    iterator end_of_storage;    //可用空间尾
    ...
}

空间结构:

vector迭代器

属于普通指针(random access iterators)

具备*, ->, ++, --, +, -, +=, -=操作

支持随机存取

 

扩容

1.如果原大小=0,则分配1,否则分配2倍

2.将原来的内容拷贝到新的vector

3.释放原vector

4.更新start, finish, end_of_storage迭代器

void insert_aux(iterator position, const T&x){
    //针对insert进行
    if (finish != end_of_storage){
        construct(finish, *(finish-1));  //将最后一个元素后移一位
        ++finish;
        T x_copy = x;
        copy_backward(position, finish - 2, finish - 1) //将position到finish-2的元素均后移
        *position = x_copy; //插入x
    }
    else {
        //如果原大小为0,新配置1
        //否则配置原大小2倍
        ...
        iterator new_start = data_allocator::allocate(len);
        iterator new_finish = new_start;
        try{
            //将原vector position前的内容拷贝到新vector
            new_finish = uninitialized_copy(start, position, new_start);    
            construct(new_finish, x);  //在position处插入x
            ++new_finish;
            //将原vector position后的内容拷贝到新vector
            new_finish = uninitialized_copy(position, finish, new_finish);
        } catch(...){
            destroy(new_start, new_finish);
            data_allocator::deallocate(new_start, len);
            throw;
        }
    
        //析构并释放原vector
        destroy(begin(), end());
        deallocate();
        
        //调整迭代器,指向新vector
        start = new_start;
        finish = new_finish;
        end_of_storage = new_start + len;
    }
}

构造与内存管理

构造函数调用fill_initialize函数

void fill_initialize(size_type n, const T& value)
{
    start = alloc_and_fill(n, value)
    finish = start + n;
    end_of_storage = finish;
}

iterator allocate_and_fill(size_type n, const T& x){
    iterator result = data_allocator::allocate(n); //配置n个元素的空间
    uninitialized_fill_n(result, n, x); //根据type traits决定使用fill_n还是反复调用construct
    return result;
}

 

常用操作:

void push_back(const T&x) {
    if (finish != end_of_storate){
        construct(finish, x);  //全局函数,根据是否有non-trivial ctor决定具体操作
        ++finish;
    }
    else
        insert_aux(end(), x);
}

void pop_back(){
    --finish;
    destroy(finish);    //全局函数,根据是否有non-trivial dtor决定具体操作
}

iterator erase(iterator position) {
    //如果删除的不是尾部元素
    if (position + 1 != end())
        copy(position + 1, finish, position);
    pop_back();
    return position;
}

iterator erase(iterator first, iterator last) {
    iterator i = copy(last, finish, first);  // copy为全局函数
    destroy(i, finish);  //destroy 为全局函数
    finish = finish - (last - first);
    return finish;
}

void clear() {erase(begin(), end());}
insert(iterator position, size_type n, const T&x)
{
    if (n != 0){
        //备用空间足够大
        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);
                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;
            //复制插入点之前元素
            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;
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值