STL中的vector也是一个常用的容器,他是一个顺序表,很多用法和接口都和list的一样。
下面来看一下vector的模拟实现
#include
#include
using namespace std;
template
class Vector
{
public:
typedef T* Iterator;
typedef const T* ConstIterator;
Vector() //空参数的构造函数
:_start(NULL), _finish(NULL), _EndofStore(NULL)
{}
Vector(size_t n, T val) //参数为n个value的构造
:_start(new T[n]), _finish(_start), _EndofStore(_start+n)
{
size_t i = 0;
for (i = 0; i < n;i++)
{
_start[i] = val;
}
_finish = _start + n;
}
Vector(const Vector
& v) //参数为Vector的拷贝构造
:_start(NULL), _finish(NULL), _EndofStore(NULL)
{
size_t size = v.Size();
if (size > 0)
{
Expand(size);
for (size_t i = 0; i < size; i++)
{
_start[i] = v._start[i];
}
_finish = _start + size;
}
}
Vector(ConstIterator first, ConstIterator last) //参数为迭代器区间的构造
:_start(NULL), _finish(NULL), _EndofStore(NULL)
{
size_t size = first - last;
if (size > 0)
{
Expand(size);
for (size_t i = 0; i < size; i++)
{
_start[i] = first[i];
}
_finish = _start + size;
}
}
~Vector() //析构函数
{
Destroy();
}
bool Checkfull()
{
return _EndofStore >= _finish;
}
void Expand(size_t n) //增容函数
{
assert(n > Capacity());
T* tmp = new T[n];
size_t size = Size();
for (size_t i = 0; i < size; i++) //扩容后拷贝原来数据
{
tmp[i] = _start[i];
}
delete[] _start;
_start = tmp;
_finish = _start + size;
_EndofStore = _start + n;
}
void Destroy() //销毁Vector的函数
{
if (_start != NULL)
{
delete[] _start;
}
_start = _finish = _EndofStore = NULL;
}
size_t Size()const
{
return _finish - _start;
}
size_t Capacity()const
{
return _EndofStore - _start;
}
//迭代器的生成器
Iterator Begin()
{
return _start;
}
Iterator End()
{
return _finish;
}
void CheckCapacity()
{
if (_finish == _EndofStore)
{
size_t newcapacity = Capacity() + 3;
Expand(newcapacity);
}
}
void Insert(Iterator pos, const T& x) //随机位置的插入函数,尾插头插都靠他
{
size_t newpos = pos - _start;
//因为要调整空间,旧的pos在调整空间以后会失效,先记录与_start的偏移量;在调整后的新空间能找到对应的新pos
CheckCapacity();
pos = _start + newpos;
for (Iterator tmp = End(); tmp > pos; tmp--)
{
*tmp = *(tmp - 1);
}
*pos = x;
_finish++;
}
void Erase(Iterator &pos) //任意位置的删除函数,尾删头删都靠他
{
Iterator end = End();
for (; pos < (--end); pos++)
{
*pos = *(pos + 1);
}
_finish--;
}
void Pushback(const T& val) //尾插
{
Insert(End(), val);
}
void Popback() //尾删
{
if (Size() != 0)
{
Iterator end= End();
Erase( --end );
}
}
void Pushfront(const T& val) //头插
{
Insert(Begin() , val);
}
void Popfront() //头删
{
if (Size() != 0)
{
Iterator start= Begin();
Erase(start);
}
}
protected:
Iterator _start;
Iterator _finish;
Iterator _EndofStore;
};
特别要注意的是增容;一旦在insert收到pos参数后再增容就会关系到原来传入pos失效的问题。我使用了pos与老的_start的偏移量来解决的;
或者可以:在传入insert参数pos之前,就增好容量,而int内部不增容的方案。我的是前者。
测试代码:
template<class T>
void PrintVector(Vector<T>& v)
{
size_t size = v.Size();
Vector<T>::ConstIterator it = v.Begin();
if (size != 0)
{
for (size_t i = 0; i < size; i++)
{
cout << it[i] << " ";
}
cout << endl;
}
}
void construct_test()
{
Vector<int> v1;
Vector<int> v2(3, 4);
Vector<int> v3(v2);
Vector<string>v4(3, "hello ");
Vector<int>::Iterator it = v2.Begin();
PrintVector<int>(v1);
PrintVector<int>(v2);
PrintVector<int>(v3);
}
void ModifiersTest()
{
Vector<int> v1(1,1);
v1.Pushback(2);
v1.Pushback(3);
v1.Pushback(4);
v1.Pushback(5);
v1.Pushfront(0);
v1.Popback();
v1.Popback();
v1.Popback();
v1.Popback();
v1.Popfront();
v1.Popfront();
v1.Popfront();
PrintVector<int>(v1);
}