zoukankan      html  css  js  c++  java
  • vector源码3(参考STL源码--侯捷):pop_back、erase、clear、insert

     vector源码1(参考STL源码--侯捷)

     vector源码2(参考STL源码--侯捷):空间分配、push_back

     vector源码(参考STL源码--侯捷)-----空间分配导致迭代器失效

    vector源码3(参考STL源码--侯捷):pop_back、erase、clear、insert

    pop_back 

    //删除尾部元素,调整大小
    void pop_back(){
        --finish; //尾端标记往前一格,表示放弃尾部元素
        destroy(finish); 
    }

    erase

    //清除(first,last)中的所有元素
    iterator erase(iterator first,iterator last){
        iterator i=copy(last,finish,first);//将last到finish的元素往前复制,从first位置开始
        destory(i,finish);
        finish=finish-(last-first);
        return first;
    }
    //清除某个位置上的元素
    iterator erase(iterator position){
        if(position+1!=end()){
            copy(position+1,finish,position);
        }
        --finish;
        destory(finish);
        return position;
    }

     

    clear

    void clear(){
        erase(begin(),end());
    }

    insert

    template <class T,class 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){
                //备用空间大于等于"新增元素"
                T x_copy=x;
                //以下计算插入点之后的现有元素个数
                const size_type elems_after=finish-position;
                iterator old_finish=finish;
                if(elems_after>n){
                    //(1)、"插入点之后的现有元素个数"大于"新增元素个数"(见图1)
                    //①从finish处开始复制范围(finish-n,finish)的元素
                    uninitialized_copy(finish-n,finish,finish);
                    finish+=n; //②vector尾部后移
                    //③将范围(position,old_finish-n)的元素移到(,old_finish)处
                    copy_backward(position,old_finish-n,old_finish);
                    //④从插入点开始填入元素
                    fill(position,position+n,x_copy);
                }
                else{
                    //(2)、"插入点之后的现有元素个数"小于"新增元素个数"(见图2)
                    //①从finish处复制n-elems_after个元素x_copy
                    uninitialized_fill_n(finish,n-elems_after,x_copy);
                    finish+=n-elems_after; //②vector尾部后移
                    //③从finish处开始复制范围(position,old_finish)的元素
                    uninitialized_copy(position,old_finish,finish);
                    finish+=elems_after; //④vector尾部后移
                    //⑤从插入点开始填入元素
                    fill(position,old_finish,x_copy);
                }
            }
            else{
                //备用空间大于等于"新增元素",即必须配置额外空间
                //首先决定新长度,旧长度的两倍,或者旧长度+新长度(见图3)
                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(...){
                    //如果发现异常,实现rollback
                    destory(new_start,new_finish);
                    data_allocator::deallocate(new_satrt,len);
                    throw;
                }
    #endif /*__STL_USE_EXCEPTIONS*/
                //以下清除并释放旧的vector
                destory(start,finish);
                deallocate();
                //调整水位标记
                start=new_start;
                finish=new_finish;
                end_of_storage=new_start+len;
                }
            }
        }
    }

    图1

    图2

    图3

  • 相关阅读:
    vue2查看大图vue-preview使用笔记
    promise使用场景
    vue2移动端使用vee-validate进行表单验证
    移动端单位换算理解
    ...
    我的promise学习笔记
    前端本地调试解决跨域的两种方法
    vue2 零星笔记
    vue2.x使用百度地图
    BZOJ 3368 约翰看山(扫描)O(N)
  • 原文地址:https://www.cnblogs.com/ybf-yyj/p/9835387.html
Copyright © 2011-2022 走看看