vector容器学习

1.  vector简介

vector就是一个动态数组,所谓动态指的是它可以自动对内存进行扩展,一般情况下不存在空间不足的情形,(max_size()函数可以知道vector的可以存的最大数量)。而且,我们还不必要去费心地管理内存,这个东西很好用比数组好用多了。所以,只要是用到new  T[ ] 来动态分配内存的时候,可以优先考虑使用这个容器。

2.Vector代码解析

部分摘录的代码:

template <class T,class Alloc=alloc>
class vector
{
public:
  typedef   T     value_type;
  typedef valuetype* pointer;
  typedef valuetype* iterator; 
  typedef valuetype& reference;
  typedef size_t    size_type;
....
protected:
     iterator start;
     iterator finish;
     iterator end_of_storage;
....
pubic:
    iterator begin{return start;}
    iterator end(){return finish;}
    size_type size() const {return size_type(end()-begin());}
    size_type capacity() const {return size_type(end_of_storage-begin());}
    reference front {return *begin()}

 }

 

3.vector使用注意事项

3.1vectorresize()reserve()区别

resize(n)  这个函数使用当前元素的个数(size),变成n,多去少补,补的时候补默认的初始化值。

resize(n,t) 用当前元素的个数(size),变成n,多去少补,补的时候补t。

reserve(n)

预分配n个元素的存储空间使得容器的容量(capacity)变成n。


为什么要介绍这两个函数呢?我们先看看,vector的内存管理策略


在 vector 对象构造期间,它先分配一个由其实现定义的默认的缓存大小。当 vector 感觉存储空间不够时,它会自动重新分配更多的内存,分配的大小是当前size的2倍,这样在使用vector的随机访问优势的时候,内存分配的负面影响也会降到最低(不然每次要重新申请内存和复制元素,效率低下),如果旧有空间装满,需要申请更大的内存,并且需要把旧有数据搬到新内存去,最后释放原来的内存此时调用析构函数。

画个图:


所以,我们可以使用reserve来避免不必要的重新分配

就是用这个函数在使用容器之前就分配适当的容量,避免不必要的浪费。


3.2 at()函数和 [ ]操作符的区别

一句话来说,at()会抛出异常,而[ ]不会去判断。但at( )的效率会有点低。

比如这样的代码:

vector<int> v;

v.clear();

cout<<v[0]<<endl;;

cout<<at(v)<<endl;  //这个就会报出异常


关于[ ]操作符重载的小问题


返回引用和返回值的区别


返回值时, 就会生成a[i]的一个临时变量,当调用完成后这个临时变量就会被销毁,所以不能当左值。

当返回引用时,返回的其实是这个变量的别名,可以重新赋值,注意不要返回临时变量的别名。

3.3 vector中的erase使用陷阱

vector<int> v;
for(vecotr<int>:: iteratoriter=v.begin();iter!=v.end();iter++)
{
      if(*iter==3)
 v.erase(iter);
}


这样使用是错误的,因为earase结束后,iter变成了野指针,iter++就产生了错误。

erase()返回值是一个迭代器,指向删除元素下一个元素。

应该这样做:

for(vector<int>::iteratorit=v.begin();it!=v.end();)
{
      if(*it==3)
            it=v.erase(it);
      else
            it++;
}

remove()算法

remove()算法不会将相应的元素删除,只会能过移动,把原来的数据覆盖


erase()函数会直接将迭代器中的位置删除

当我们有个连续内存的容器时,使用erase-remove方法习惯用法。

v.erase(remove(v.begin(),v.end(),10),v.end());


3.4使用swap()技巧,除去多余的容量

vector<int>(v).swap(v);//使达到没有多余的容量

vector<int>().swap(v);//清空内存

 

3.5 把vector数据传给指针

vector<int> v; 

&v[0];

当然要判空

if(!v.empty()){ //使用&v[0];}

//注意这里要用empty()判断,不要用v.size()==0来判断。


4.vector的使用

我们可以通过继承vector来使用这个优秀的容器

 #include<iostream>  

 #include<vector>  

 using namespace std;  
 struct Item{  
     int id;  
     int price;  
  }; 
class ItemBag:protected vector<Item*> 
{ 
    public: 
        ItemBag(size_t inisize,size_tmaxsize); 
        virtual ~ItemBag(); 
    public: 
        void PrintInfo(); 
    public: 
        int GetFreePos(); 
        int AddItem(Item *pItem); 
        Item* DelItem(int id); 
    protected: 
        size_t m_nInitSize; 
        size_t m_nMaxSize; 

}; 

ItemBag::ItemBag(size_tinisize,size_t maxsize) 
    :m_nInitSize(inisize) 
    ,m_nMaxSize(maxsize) 
{ 
    this->clear(); 
    this->reserve(m_nMaxSize); 
    this->resize(m_nInitSize); 
} 

 
ItemBag::~ItemBag() 

{ 
    for(size_ti=0;i<this->size();++i) 
    { 
        Item *pItem=at(i); 
        if(pItem!=NULL) 
          delete pItem; 
    } 

} 

voidItemBag::PrintInfo() 

{ 
    cout<<"背包大小是"<<this->m_nInitSize<<endl; 
    cout<<"背包容量是"<<this->m_nMaxSize<<endl; 

} 

intItemBag::GetFreePos() 

{ 
    for(size_ti=0;i<this->size();++i) 
    { 
        if(at(i)==NULL) 
         return i; 
    } 
    return -1; 

} 

intItemBag::AddItem(Item* pItem) 
{ 

    if(pItem==NULL) 
        return -1; 
    int pos=GetFreePos(); 
    if(pos>=0) 
    { 
        (*this)[pos]=pItem; 
        return 0; 
    } 
    return -1; 
} 

Item*ItemBag::DelItem(int id) 
{ 
    for(size_ti=0;i<this->size();++i) 
    { 
        Item *pItem=at(i);   
       if(pItem&&pItem->id==id) 
        { 
            (*this)[i]=NULL; 
            return pItem; 
        } 
    } 
    return NULL; 
} 

int main() 
{ 
    ItemBag bag(10,100); 
    bag.PrintInfo(); 
    Item *pItem=new Item; 
    pItem->id=0; 
    pItem->price=12; 
    bag.AddItem(pItem); 
   cout<<bag.GetFreePos()<<endl; 
    return 0; 
}   

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值