• STL容器之vector


    vector概述

       vector的数据安排以及操作方式,与数组非常类似,两者的唯一差别在于空间的运用的灵活性。数组是静态空间,一旦配置了就不能改变:要换个大(或小)一点的房子,可以,一切细节都由自己来:首先配置一块新空间,然后将元素从旧址一一搬往新址,再把原来的空间释还给系统。vector是动态空间,随着元素的加入,它的内部机制会自行扩展空间以容纳新元素。以此,vector的运用对于内存的合理利用与运用的灵活性有很大的帮助,我们也不必因为害怕空间不足而一开始就要求一个大块头的数组了,我们可以安心使用vector,吃多少用多少。

    vector定义摘要

    以下是vector定义的源代码摘录

    //alloc SGI STL的空间配置器

    template <class T,class Alloc = alloc>

    class vector

    {

      public:

      //vectord的嵌套类别定义

      typedef  T           value_type; 

      typedef  value_type*  pointer;

      typedef  value_type*  iterator;

      typedef  value_tpe&  reference;

      typedef  size_t       size_type;

      typdefe  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::deallocate(start,end_of_storage - start);

      }

      void  fill_initialize(size_type n, const T& value)

      {

    start = allocate_add_fill(n,value);

    finish = start + n;

    end_of_storage = finish;

      }

     

    public:

      iterator    begin() { return start; }//返回vector

      iterator    end() { return finish; }//返回vector

      size_type  size() const { return  size_type(end() - begin()); } //获得vector大小

      size_type  capacity() const  //获得vector空间大小

      {  

    return size_type( end_of_storage - begin()); 

      }  

      bool empty() const { return begin() == end();}//判断vector是否为空

      reference operator[] (size_type n) { return *(begin() + n) ; }//重载[]运算符

     

     vector():start(0),finish(0),end_of_storage(0) {}//无参构造

     explicit vector(size_type n) { fill_initialize(n,T()); }//指定vector初始大小

     vector(size_type n, const T& value)//指定vector初始大小和初始值

     {

       fill_initialize(n,value); 

     }

    vector(int n,const T& value){fill_initialize(n,value); }

    vector(long n,const T& value){fill_initialize(n,value); }

     

    ~vector()

    {

      destory(start,finish);

      deallocate();

    }

    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, positon);

      -- finish;

      destroy(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());} //清空vector

     

    protected:

       //配置空间并填满内容

       iterator allocate_and_fill(size_type n , const  T& x)

    {

       iterator resualt = data_allocator::allocate(n);

       uninitialized_fill_n(result,n,x);//全局函数

       return resualt;

    }

    };

    vector 的迭代器

       vector 维护的是一个连续的线性空间,所以不论其元素类型为何,普通指针

    都可以作为vector的迭代器而满足所有必要条件,因为vector迭代器所需要的

    操作行为,如operator*,operator->,operator++,operator--,operator+,operator-,

    operator+=,operator-=,普通指针天生就具备。vector支持随机存取,而普通指针正有这样的能力。

     

    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的类型就是Shap*

     

     

    vector实例:

    #include<vector>

    #include<iostream>

    #include<algorithm>

    using namespace std;

     

    int main(int argc, char* argv[])

    {

    int i;

    vector<int> iv(2,9);//初始大小为2  初始值为9

    cout<<"size="<<iv.size()<<endl;   //size = 2 

    cout<<"capacity="<<iv.capacity()<<endl; //capacity = 2

        cout<<endl;

     

    iv.push_back(1);//尾部插入1

    cout<<"size="<<iv.size()<<endl;   //size = 3 

    cout<<"capacity="<<iv.capacity()<<endl; //capacity = 4

        cout<<endl;

     

    iv.push_back(2);//尾部插入2

    cout<<"size="<<iv.size()<<endl;   //size = 4 

    cout<<"capacity="<<iv.capacity()<<endl; //capacity = 4

        cout<<endl;

     

    iv.push_back(3);//尾部插入3

    cout<<"size="<<iv.size()<<endl;   //size = 5

    cout<<"capacity="<<iv.capacity()<<endl; //capacity = 8

        cout<<endl;

     

    iv.push_back(4);//尾部插入4

    cout<<"size="<<iv.size()<<endl;   //size = 6

    cout<<"capacity="<<iv.capacity()<<endl; //capacity = 8

        cout<<endl;

     

    for(i=0;i<iv.size();i++)  //输出 9 9 1 2 3 4

    {

    cout<<iv[i]<<' ';

    }

    cout<<endl;

     

    iv.push_back(5);//尾部插入5

    cout<<"size="<<iv.size()<<endl;   //size = 7

    cout<<"capacity="<<iv.capacity()<<endl; //capacity = 8

        cout<<endl;

     

        for(i=0;i<iv.size();i++)  //输出 9 9 1 2 3 4 5

    {

    cout<<iv[i]<<' ';

    }

    cout<<endl;

     

    iv.pop_back();//删除尾部元素

    iv.pop_back();//删除尾部元素

    cout<<"size="<<iv.size()<<endl;  //size = 5

    cout<<"capacity="<<iv.capacity()<<endl;  //capacity=8

        cout<<endl;

     

    iv.pop_back();//删除尾部元素

        cout<<"size="<<iv.size()<<endl;  //size = 4

    cout<<"capacity="<<iv.capacity()<<endl;  //capacity=8

        cout<<endl;

     

        for(i=0;i<iv.size();i++)  //输出 9 9 1 2 

    {

    cout<<iv[i]<<' ';

    }

    cout<<endl;

     

    vector<int>::iterator ivite = find(iv.begin(),iv.end(),1);//查找元素为1的位置

    if(ivite) iv.erase(ivite);//删除元素1

        cout<<"size="<<iv.size()<<endl;  //size = 3

    cout<<"capacity="<<iv.capacity()<<endl;  //capacity=8

        for(i=0;i<iv.size();i++)  //输出 9 9  2 

    {

    cout<<iv[i]<<' ';

    }

    cout<<endl;

     

    ivite = find(iv.begin(),iv.end(),2);//查找元素为2的位置

        if(ivite) iv.insert(ivite,3,7);//2前插入37

        cout<<"size="<<iv.size()<<endl;  //size = 2

    cout<<"capacity="<<iv.capacity()<<endl;  //capacity=8

        for(i=0;i<iv.size();i++)  //输出 9 9 7 7 7 2

    {

    cout<<iv[i]<<' ';

    }

    cout<<endl;

     

    iv.clear();//清空

    cout<<"size="<<iv.size()<<endl;  //size = 0

    cout<<"capacity="<<iv.capacity()<<endl;  //capacity=8

    return 0;

    }

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

  • 相关阅读:
    MySQL Show Processlist 整理
    由linkedin数据库泄漏引发的思考[转发]
    MySQL 严重 Bug 用户登陆漏洞[转发]
    关于博客的开始
    Linux共享库位置配置
    getopt详解
    git使用
    ArrayList读源码心得
    HashMap内部实现机制及优化第一篇
    如何才能做一个好网站系列 第三篇 最初的思路
  • 原文地址:https://www.cnblogs.com/marshhu/p/3454408.html
Copyright © 2020-2023  润新知