C++模拟实现vector代码分析(C++,vector,开发技术)

时间:2024-04-30 02:51:20 作者 : 石家庄SEO 分类 : 开发技术
  • TAG :

vector的模拟实现

#include<iostream>usingnamespacestd;#include<assert.h>namespacemyVector{ template<classT> classvector { public: //Vector的迭代器是一个原生指针 typedefT*iterator; typedefconstT*const_iterator; /// //构造和销毁 vector() :_start(nullptr) ,_finish(nullptr) ,_endOfStorage(nullptr) {} vector(size_tn,constT&value=T()) :_start(nullptr) ,_finish(nullptr) ,_endOfStorage(nullptr) { reserve(n); while(n--) { push_back(value); } } /* *理论上讲,提供了vector(size_tn,constT&value=T())之后 *vector(intn,constT&value=T())就不需要提供了,但是对于: *vector<int>v(10,5); *编译器在编译时,认为T已经被实例化为int,而10和5编译器会默认其为int类型 *就不会走vector(size_tn,constT&value=T())这个构造方法, *最终选择的是:vector(InputIteratorfirst,InputIteratorlast) *因为编译器觉得区间构造两个参数类型一致,因此编译器就会将InputIterator实例化为int *但是10和5根本不是一个区间,编译时就报错了 *故需要增加该构造方法 */ vector(intn,constT&value=T()) :_start(newT[n]) ,_finish(_start+n) ,_endOfStorage(_finish) { for(inti=0;i<n;++i) { _start[i]=value; } } //若使用iterator做迭代器,会导致初始化的迭代器区间[first,last)只能是vector的迭代器 //重新声明迭代器,迭代器区间[first,last)可以是任意容器的迭代器 template<classInputIterator> vector(InputIteratorfirst,InputIteratorlast) { while(first!=last) { push_back(*first); ++first; } } voidswap(vector<T>&v) { std::swap(_start,v._start); std::swap(_finish,v._finish); std::swap(_endOfStorage,v._endOfStorage); } vector(constvector<T>&v) :_start(nullptr) ,_finish(nullptr) ,_endOfStorage(nullptr) { //现代写法,资本家写法 vector<T>temp(v.begin(),v.end()); swap(tmp); } vector<T>&operator=(vector<T>v) { swap(v); return*this; } ~vector() { if(_start) { delete[]_start; _start=_finish=_endOfStorage=nullptr; } } / //迭代器相关 iteratorbegin() { return_start; } iteratorend() { return_finish; } const_iteratorcbegin()const { return_start; } const_iteratorcend()const { return_finish; } // //容量相关 size_tsize()const { return_finish-_start; } size_tcapacity()const { return_endOfStorage-_start; } boolempty()const { return_start==_finish; } voidreserve(size_tn) { if(n>capacity()) { size_toldSize=size(); //1.开辟新空间 T*tmp=newT[n]; //2.拷贝元素 //这里直接使用memcpy会有问题吗?请思考下 //if(_start) // memcpy(tmp,_start,sizeof(T)*size); if(_start) { for(size_ti=0;i<oldSize;++i) tmp[i]=_start[i]; //3.释放旧空间 delete[]_start; } _start=tmp; _finish=_start+oldSize; _endOfStorage=_start+n; } } voidresize(size_tn,constT&value=T()) { //1.如果n小于当前的size,则数据个数缩小到n if(n<=size()) { _finish=_start+n; return; } //2.空间不够则增容 if(n>capacity()) reserve(n); //3.将size扩大到n iteratorit=_finish; _finish=_start+n; while(it!=_finish) { *it=value; ++it; } } /// //元素访问 T&operator[](size_tpos) { assert(pos<size()); return_start[pos]; } constT&operator[](size_tpos)const { assert(pos<size()); return_start[pos]; } T&front() { return*_start; } constT&front()const { return*_start; } T&back() { return*(_finish-1); } constT&back()const { return*(_finish-1); } / //vector的修改操作 iteratorinsert(iteratorpos,constT&x) { assert(pos<=_finish); //空间不够先进行增容 if(_finish==_endOfStorage) { size_tn=pos-_start; size_tnewCapacity=(0==capacity())?1:capacity()*2; reserve(newCapacity);//如果发生了增容,重新开辟空间后,reserve会更新start和finish,但是不会更新pos,原空间被释放掉,迭代器失效了,所以需要重置pos pos=_start+n; } iteratorend=_finish-1; while(end>=pos) { *(end+1)=*end; --end; } *pos=x; ++_finish; returnpos; } //返回删除数据的下一个数据 //方便解决:一边遍历一边删除的迭代器失效问题 iteratorerase(iteratorpos) { //挪动数据进行删除 iteratorbegin=pos+1; while(begin!=_finish){ *(begin-1)=*begin; ++begin; } --_finish; returnpos; } voidpush_back(constT&x)//防止深拷贝,尽量用引用传参 { insert(end(),x); } voidpop_back() { erase(end()-1); } private: iterator_start; //指向数据块的开始 iterator_finish; //指向最后有效数据的下一个位置 iterator_endOfStorage;//指向存储容量的尾 };}

使用memcpy拷贝问题

假设模拟实现的vector中的reserve接口中,使用memcpy进行的拷贝,以下代码会发生什么问题?

intmain(){ bite::vector<swx::string>v; v.push_back("1111"); v.push_back("2222"); v.push_back("3333"); return0;}

问题分析:

  • memcpy是逐字节拷贝,将一段内存空间中内容原封不动的拷贝到另外一段内存空间中

  • 如果不涉及资源管理,memcpy既高效又不会出错,但如果涉及到资源管理时,就会出错,因为memcpy的拷贝实际是浅拷贝。

C++模拟实现vector代码分析

C++模拟实现vector代码分析

C++模拟实现vector代码分析

C++模拟实现vector代码分析

如果对象中涉及到资源管理时,千万不能使用memcpy进行对象之间的拷贝,因为memcpy是浅拷贝,可能会引起一系列浅拷贝问题,所以我们要使用赋值运算符来完成,如果不涉及资源管理,那就正常赋值,如果涉及资源管理,那赋值运算符中也已经实现了深拷贝。

 </div> <div class="zixun-tj-product adv-bottom"></div> </div> </div> <div class="prve-next-news">
本文:C++模拟实现vector代码分析的详细内容,希望对您有所帮助,信息来源于网络。
上一篇:Springboot中filter的原理与注册方法是什么下一篇:

15 人围观 / 0 条评论 ↓快速评论↓

(必须)

(必须,保密)

阿狸1 阿狸2 阿狸3 阿狸4 阿狸5 阿狸6 阿狸7 阿狸8 阿狸9 阿狸10 阿狸11 阿狸12 阿狸13 阿狸14 阿狸15 阿狸16 阿狸17 阿狸18