永发信息网

stl vector 内部是用什么实现

答案:3  悬赏:70  手机版
解决时间 2021-03-05 13:45
stl vector 内部是用什么实现
最佳答案
《STL系列》之vector原理及实现
  最近忙得蛋疼,但还是想写点属于自己的东西。也不知道写点啥,最后决定试着自己实现STL中常用的几个集合,一来加深自己对STL的理解,二来看看自己是否有这个能力实现。实现目标就是:1能和STL兼容;2最大化的实现STL中的接口并保持一致。即将STL中的集合换成我写的也能用。这篇博客介绍的是vector的原理及实现。
  先把vector的大致实现说一下,后面会给出完整的源码。
  新增元素:Vector通过一个连续的数组存放元素,如果集合已满,在新增数据的时候,就要分配一块更大的内存,将原来的数据复制过来,释放之前的内存,在插入新增的元素。插入新的数据分在最后插入push_back和通过迭代器在任何位置插入,这里说一下通过迭代器插入,通过迭代器与第一个元素的距离知道要插入的位置,即int index=iter-begin()。这个元素后面的所有元素都向后移动一个位置,在空出来的位置上存入新增的元素。


  void insert(const_iterator iter,const T& t )
{
int index=iter-begin();
if (index<size_)
{
if (size_==capacity_)
{
int capa=calculateCapacity();
newCapacity(capa);
}
memmove(buf+index+1,buf+index,(size_-index)*sizeof(T));
buf[index]=t;
size_++;
}
}


  删除元素:删除和新增差不多,也分两种,删除最后一个元素pop_back和通过迭代器删除任意一个元素erase(iter)。通过迭代器删除还是先找到要删除元素的位置,即int index=iter-begin();这个位置后面的每个元素都想前移动一个元素的位置。同时我们知道erase不释放内存只初始化成默认值。
  删除全部元素clear:只是循环调用了erase,所以删除全部元素的时候,不释放内存。内存是在析构函数中释放的。


  iterator erase(const_iterator iter)
{
int index=iter-begin();
if (index<size_ && size_>0)
{
memmove(buf+index ,buf+index+1,(size_-index)*sizeof(T));
buf[--size_]=T();
}
return iterator(iter);
}
全部回答
《STL系列》之vector原理及实现   最近忙得蛋疼,但还是想写点属于自己的东西。也不知道写点啥,最后决定试着自己实现STL中常用的几个集合,一来加深自己对STL的理解,二来看看自己是否有这个能力实现。实现目标就是:1能和STL兼容;2最大化的实现STL中的接口并保持一致。即将STL中的集合换成我写的也能用。这篇博客介绍的是vector的原理及实现。   先把vector的大致实现说一下,后面会给出完整的源码。   新增元素:Vector通过一个连续的数组存放元素,如果集合已满,在新增数据的时候,就要分配一块更大的内存,将原来的数据复制过来,释放之前的内存,在插入新增的元素。插入新的数据分在最后插入push_back和通过迭代器在任何位置插入,这里说一下通过迭代器插入,通过迭代器与第一个元素的距离知道要插入的位置,即int index=iter-begin()。这个元素后面的所有元素都向后移动一个位置,在空出来的位置上存入新增的元素。   void insert(const_iterator iter,const T& t ) { int index=iter-begin(); if (index<size_) { if (size_==capacity_) { int capa=calculateCapacity(); newCapacity(capa); } memmove(buf+index+1,buf+index,(size_-index)*sizeof(T)); buf[index]=t; size_++; } }   删除元素:删除和新增差不多,也分两种,删除最后一个元素pop_back和通过迭代器删除任意一个元素erase(iter)。通过迭代器删除还是先找到要删除元素的位置,即int index=iter-begin();这个位置后面的每个元素都想前移动一个元素的位置。同时我们知道erase不释放内存只初始化成默认值。   删除全部元素clear:只是循环调用了erase,所以删除全部元素的时候,不释放内存。内存是在析构函数中释放的。   iterator erase(const_iterator iter) { int index=iter-begin(); if (index<size_ && size_>0) { memmove(buf+index ,buf+index+1,(size_-index)*sizeof(T)); buf[--size_]=T(); } return iterator(iter); }   迭代器iteraotr是STL的一个重要组成部分,通过iterator可以很方便的存储集合中的元素.STL为每个集合都写了一个迭代器, 迭代器其实是对一个指针的包装,实现一些常用的方法,如++,--,!=,==,*,->等, 通过这些方法可以找到当前元素或是别的元素. vector是STL集合中比较特殊的一个,因为vector中的每个元素都是连续的,所以在自己实现vector的时候可以用指针代替,如typedef T* iterator;typedef const T* const_iterator,如果STL中的函数能方便的操作自己写的集合,实现的迭代器最好继承std::iterator<std::forward_iterator_tag,T>。我实现vector的迭代器大概是这个样子:   template<typename T>   class viterator:public std::iterator<std::forward_iterator_tag,T>{}   后面会给出完整的代码,std::iterator<std::forward_iterator_tag,T>的源码如下:   template<class _Category, class _Ty, class _Diff = ptrdiff_t, class _Pointer = _Ty *, class _Reference = _Ty&> struct iterator { // base type for all iterator classes typedef _Category iterator_category; typedef _Ty value_type; typedef _Diff difference_type; typedef _Diff distance_type; // retained typedef _Pointer pointer; typedef _Reference reference; };   Iterator其中没有任何成员,只是定义了一组类型,所以继承它并不会让你的struct变大,这组类型是STL的内部契约,STL中的函数假设每个迭代器都定义了这些类型,所以只要你的迭代器定义了这些类型,就可以和STL函数集合一起使用。   我的vector实现源码如下:   View Code   实例代码级运行结果如下:   struct Point { Point(int x_=0,int y_=0):x(x_),y(y_){} int x,y; }; bool operator<(const Point& p1,const Point& p2) { if(p1.x<p2.x) { return true; }else if(p1.x>p2.x) { return false; } return p1.y<p2.y; } void cvectorTest() { cvector<Point> vect; for (int i=0;i<10;i++) { Point p(i,i); vect.push_back(p); } cvector<Point>::iterator iter=vect.begin(); while (iter!=vect.end()) { cout<< "[" << iter->x << " " << iter->y <<"], "; ++iter; } iter=vect.begin()+5; vect.insert(iter,Point(55,55)); iter=vect.end()-3; vect.insert(iter,Point(77,77)); cout<<endl<<endl<<"插入两个元素后:"<<endl; iter=vect.begin(); while (iter!=vect.end()) { cout<< "[" << iter->x << " " << iter->y <<"], "; ++iter; } std::sort(vect.begin(),vect.end()); cout<<endl<<endl<<"排序后:"<<endl; iter=vect.begin(); while (iter!=vect.end()) { cout<< "[" << iter->x << " " << iter->y <<"], "; ++iter; } vect.erase(vect.begin()+10); vect.erase(vect.begin()+10); cout<<endl<<endl<<"删除之前新增的两个元素"<<endl; iter=vect.begin(); while (iter!=vect.end()) { cout<< "[" << iter->x << " " << iter->y <<"], "; ++iter; } vect.clear(); cout<<endl<<endl<<"执行clear之后"<<endl; cout<<"size="<<vect.size()<<",capacity="<<vect.capacity(); cvector<Point> vect1; for (int i=10;i<20;i++) { Point p(i,i); vect1.push_back(p); } cout<<endl<<endl<<"从别的cvector复制数据:"<<endl; cvector<Point> vect2(vect1.begin(),vect1.end()); vect2.pop_back(); vect2.pop_back(); for(int i=0;i<vect2.size();i++) { cout<<"["<<vect2[i].x<<","<<vect2[i].y<<"], "; } cout<<endl; }   之后还会有list,set,map等的实现,敬请期待......
vector 就是就是一个动态数组,并且按照插入需要会自动增加长度,因此在需要频繁随机访问并且少插入删除时使用,大多数排序算法也是这样要求的
我要举报
如以上问答信息为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
川大附中晋阳好不好
什么情况下可以计取清水模板
微信象棋69关怎么过
百顺彩板我想知道这个在什么地方
打拳击沙袋练什么肌肉
以枯山水为代表的写意庭园的极盛时期是:[20
在水一方休闲农庄地址有知道的么?有点事想过
和朋友聊微信怎樣打開她的攝像頭
小米手环,要是用来电提醒功能,来了电话,想
职场谈星座 有你什么事儿吗
小村上地址有知道的么?有点事想过去
怎么看是不是单向好友
NCsoft公司和Nexon谁厉害
【初中一年级英语单词】从小学到初中一年级的
沙坝村在哪里啊,我有事要去这个地方
推荐资讯
李宁是上市公司吗
地球上水圈的主体是A. 冰川水B. 海洋水C. 江
motoz摩音jbl能当电池用吗
什么牌子汽车座垫好
尊师的话!
甘肃临夏回族自治州2016年退休职工认证必须到
镇江市丹阳那里有卖成人保健的
矿工路南74号楼在哪里啊,我有事要去这个地方
【啼组词】“啼”怎样组词。
广州科技贸易职业学院是不是升到了3A?
长兴同欣大药房在哪里啊,我有事要去这个地方
泉州市信驭汽车贸易有限公司怎么去啊,有知道
正方形一边上任一点到这个正方形两条对角线的
阴历怎么看 ?