【STL】 vector 模拟实现

    上一篇博客说了一下list的使用,其实vector用法基本上和list是一样的,所以此篇博客就只模拟实现以下vector。vector你可以把它理解成一个顺序表或者数组。只是STL里的vector是由三个迭代器来维护的:_start(数据存放开始的位置),_finish(数据存放结束位置的下一个),_endofstorage(容量的最后一个位置)。vector里的迭代器其实就是个指针。来看看代码实现:

#include<iostream>
#include<vector>
using namespace std;

template<class T>
class MyVector
{
public:
	typedef T* Iterator;
	typedef const T* ConstIterator;

	MyVector(size_t n=3)      //构造函数,初始化给3个T类型容量
		:_start(new T[n]), _finish(_start), _end_of_storage(_start+n)
	{
	}
	MyVector(const MyVector<T>& v)   //拷贝构造
	{
		if (v._finish - v._start > _finish - _start)
		{
			delete[] _start;
			_start = new T[v._finish - v._start];
			_finish = _start;
		}
		for (Iterator tmp = v._start; tmp != v._finish; tmp++)
		{
			*(_finish) = *tmp;
			_finish++;
		}
		_end_of_storage = _finish;
	}
	void PushBack(const T& x)   //尾插,这里注意,即使调用的insert里检查了容量,尾插函数仍需检测
	{
		CheckCapacity();
		Insert(End(), x);
	}
	void PopBack()
	{
		Iterator pos = End();   //前置的--因为返回的是临时变量的值,所以不能直接对End()函数进行--
		Erase(--pos);
	}

	void Insert(Iterator pos, const T& x)
	{
		CheckCapacity();
		for (Iterator tmp = End(); tmp != pos;tmp--)
		{
			*tmp = *(tmp - 1);
		}
		*pos = x;
		_finish++;
	}

	void Erase(Iterator pos)
	{
		Iterator end = End();
		for (Iterator tmp = pos; tmp != (--end); tmp++)
		{
			*tmp = *(tmp + 1);
		}
		_finish--;
	}

	size_t Size()
	{
		return _finish - _start;
	}
	/************迭代器部分***********/
	Iterator Begin()
	{
		return _start;
	}
	Iterator End()
	{
		return _finish;
	}
	/*Iterator operator++(int)
	{
		Iterator tmp = *this;
		tmp++;
		return tmp;
	}
	Iterator& operator++()
	{
		Iterator tmp = *this;
		tmp++;
		return *this;
	}
	Iterator operator--(int)
	{
		Iterator tmp = *this;
		tmp--;
		return tmp;
	}
	Iterator& operator--()
	{
		Iterator tmp = *this;
		tmp--;
		return *this;
	}
	*/
private:
	void CheckCapacity()
	{
		if (_finish == _end_of_storage)
		{
			Iterator new_start = new T[2 * Size()];   //一次扩容原来的两倍
			Iterator new_finish = new_start;
			for (Iterator i = Begin(); i != End(); i++,new_finish++)
			{
				*new_finish = *i;
			}
			delete[] _start;
			_start = new_start;
			_finish = new_finish;
			_end_of_storage = _start + 2 * Size();
		}
	}
private:
	Iterator _start;
	Iterator _finish;
	Iterator _end_of_storage;
};


void TestVector()
{
	MyVector<int> v;
	v.PushBack(1);
	v.PushBack(2);
	v.PushBack(3);
	v.PushBack(4);
	MyVector<int>::Iterator it;
	for (it = v.Begin(); it != v.End(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;
	v.PopBack();
	v.PopBack();
	for (it = v.Begin(); it != v.End(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;
	MyVector<int> v1(v);
	for (it = v1.Begin(); it != v1.End(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;
}

写vector时,犯了好多愚蠢的错误:

1.因为pushpack()函数是调用Insert()函数实现的,而Insert()函数内部有检测容量,所以刚开始Pushpack()就没有检测,程序崩溃了。因为在Insert里扩容时,等于说重新开辟了一块更大的内存,那你Pushback传过来的End()位置将永远也找不到,因为那块内存已经被释放了。

2.其实这里的迭代器它就是一个指针,根本没必要再对它的++,--,什么的进行重载,我好像是陷入了list的迷阵中无法自拔-_-....

    为什么会这么凌乱呢,因为写vector时,我边看《老九门》边敲代码。。。回头再看看真是。。。所以,作为程序员,该敲代码时还是老老实实敲吧。。。

    我这里在拷贝构造时,只开辟了有效值个数,考虑到实际中拷贝后应该不会再插入,所以这样做也是一种省空间的做法。

    vector包含的函数当然不止这些,有兴趣可以查阅STL库看看。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值