【STL】vector的模拟实现

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);
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值