对于实现vector的模拟实现是,我们应先参考一下前辈的源代码进行辅助学习,在这里我保留主要思想(忽略部分细节),来实现vector的模拟实现
在这里我们实现迭代器是仍用原生指针来代替,这里我们构建基本框架:
namespace bit
{
template<class T>
class vector
{
typedef T* iterator;
public:
vector()
:_start(nullptr)
,_finish(nullptr)
,_end_of_storage(nullptr)
{}
~vector()
{
_start=_finish=_end_of_storage=nullptr;
}
private:
iterator _start;
iterator _finish;
iterator _end_of_storage;
}
}
接下来我们逐个实现函数的功能:
一.尾插:
void push_back(const T& x)
{
if(_finish=_end_of_storage)
{
revese(capacity()==0?4:capacity()*2)
}
*_finish=x;
_finish++;
}
二.扩容函数:
void reverse(size_t n)
{
if(n>capacity())
{
size_t zs=size();
T* temp=new T[n];
if(_start)
{
memcpy(temp,_start,sizeof(T)*size());
delete[] _start;
}
_start=temp;
_finish=_start+sz;
_end_of_storage=_start+n;
}
}
三.其他分支函数
size_t capacity() const
{
return _end_of_storage-_start;
}
T& [](size_t index)
{
return _start[index];
}
size_t size() const
{
return _finish-_start;
}
iterator begin()
{
return _start;
}
iterator end()
{
return _finish;
}
四.尾部删除函数
void pop_back()
{
--_finish;
}
五.插入函数
void insert(iterator index,const T& x )
{
if(_finish==_end_of_storage)
{
reverse(cacpacity()==0?4:capacity()*2);
}
iterator end=_finish-1;
while(end>=index)
{
*(end+1)=*end;
--end;
}
*pos=x;
++_finish;
}
接下来我们讲一下vector迭代器实现的问题
第一类这里我们以插入函数为例:
auto p=find(v.begin().v.end().3);
if(p!=v.end())
{
v.insert(p,30);
}
这里我们以尾插四个数据,这里我们就需要扩容,扩容是这里就会出现问题:
在我们扩容时候,会将原来的部分拷贝到新空间,释放旧空间,但是此时指针index仍指向
原来旧的位置,导致index变为野指针,这时就会导致迭代器的失效。
改进方案如下:
void insert(iterator index,const T& x )
{
if(_finish==_end_of_storage)
{
size_t len=index-_start;
reverse(cacpacity()==0?4:capacity()*2);
index=_start+len;
}
iterator end=_finish-1;
while(end>=index)
{
*(end+1)=*end;
--end;
}
*index=x;
++_finish;
}
即让指针指向新的位置即可。
但是这里我们仍需注意一个问题,那就是如果在p位置插入数据后,不要再访问p,因为p可能失效了
六.删除函数
void erase(iterator index)
{
iterator begin=index+1;
while(begin<_finish)
{
*(begin-1)=*(begin);
++begin;
}
--_finish;
}
这是我们自己写的erase函数,但是有的版本也会导致失效,因为有的erase会进行缩容,此时index仍指向原来的位置,这样就会导致迭代器失效的问题
以上就是本篇的所有内容,希望以上内容对你有所帮助!!!