vector的模拟实现

vector的模拟实现

vector.h

1、迭代器的实现

#pragma once
#include <assert.h>

namespace JPC
{
	template<class T>
	class vector
	{
	public:
		typedef T* iterator;
		typedef const T* const_iterator;
		//迭代器的实现
		//普通迭代器
		iterator begin()
		{
			return _start;
		}

		iterator end()
		{
			return _finish;
		}

		//const迭代器
		const iterator begin()const
		{
			return _start;
		}

		const iterator end()const 
		{
			return _finish;
		}

2、构造函数与析构函数

//构造函数
		vector()
			:_start(nullptr)
			,_finish(nullptr)
			,_end_of_storage(nullptr)
		{}

		//析构函数
		~vector()
		{
			delete[] _start;
			_start = _finish = _end_of_storage = nullptr;	
		}

3、求出 capacity \ size 以及实现 operator[ ]

//求出 capacity
		size_t capacity()const 
		{
			return _end_of_storage - _start;
		}
		
		//求出 size
		size_t size()const
		{
			return _finish - _start;
		}

		//实现:[]
		T& operator[](size_t pos)
		{
			assert(pos<size());
			return _start[pos];
		}

		const T& operator[](size_t pos)const 
		{
			assert(pos < size());
			return _start[pos];
		}

4 、预先开辟空间

//预先开辟空间
		void reserve(size_t n)
		{
			size_t sz = size();//预先保留 size() 的大小,因为一旦delete过后,size() 就变为0了
			if (n>capacity())
			{
				T* tmp = new T[n];
				if (_start) //如果原来的数组不为空,就把数据拷贝到tmp空间中
				{
					memcpy(tmp,_start,sizeof(T)*size());
					delete[] _start;
				}

				//确定新空间的 _start \ _finish \ _end_of_storage
				_start = tmp;
				_finish = _start + sz;
				_end_of_storage = _start + n;
			}
		}

5、尾插、尾删

//尾插
		void push_back(const T& x) //用引用传参,如果T是自定义类型的,就不需要拷贝构造(深拷贝),减少消耗
		{
			检测是否需要扩容
			//if (_finish==_end_of_storage)
			//{
			//	reserve(capacity()==0 ? 4:capacity()*2);
			//}

			//*_finish = x;
			//++_finish;
			insert(end(),x);
		}

		//尾删
		void pop_back()
		{
			//防止删除到越界了
			assert(_finish>_start);
			--_finish;
		}

6、任意位置插入、删除

//插入
		void insert(iterator pos,const T& x)
		{
			assert(pos>=_start && pos<=_finish);
			//检测是否需要扩容
			if (_finish==_end_of_storage)
			{
				//在扩容前需要记录好pos的位置
				size_t len = pos - _start;
				reserve(capacity()==0 ? 4:capacity()*2);
				//扩容后需要重新确定pos的位置
				pos = _start + len;
			}

			//挪动数据
			iterator end = _finish - 1;
			while (end>=pos)
			{
				*(end+1) = *end;
				--end;
			}

			//插入数据
			*pos = x;
			++_finish;
		}


		//删除
		//stl 规定 vector::erase 返回删除位置的下一个位置的迭代器(地址)
		iterator erase(iterator pos)
		{
			assert(pos>=_start && pos<_finish);

			iterator begin = pos;
			while (begin<_finish-1)
			{
				*begin = *(begin+1);
				++begin;
			}
			--_finish;

			return pos;
		}


	private:
		iterator _start; //_start为vector存储的首个数据的地址(指针)
		iterator _finish; //_finish为存储的末尾数据的下一个数据的地址
		iterator _end_of_storage; //_end_of_storage为vector内开辟的最后一个空间的下一个空间的地址
	};

7、test_vector

void test_vector1()
	{
		vector<int> v;
		v.push_back(1);
		v.push_back(2);
		v.push_back(3);
		v.push_back(4);
		v.push_back(5);

		for (size_t i=0;i<v.size();++i)
		{
			cout<< v[i] <<" ";
		}
		cout << endl;

		vector<int>::iterator it = v.begin();
		while (it != v.end())
		{
			cout<< *it <<" ";
			++it; //切莫忘记了
		}
		cout << endl;

		//范围for ( 底层是迭代器,傻瓜式的替换 v.begin() 和 v.end() )
		for (auto e:v)
		{
			cout<< e <<" ";
		}
		cout << endl;

		v.pop_back();
		v.pop_back();
		for (size_t i=0;i<v.size();++i)
		{
			cout<< v[i] <<" ";
		}
		cout << endl;

	}

	void Func(const vector<int>& v)
	{
		vector<int>::const_iterator it = v.begin();
		while (it != v.end())
		{
			//++*it; //无法改变 *it 的值
			cout<< *it <<" ";
			++it;
		}
		cout << endl;
	}



	void test_vector()
	{
		//测试 insert 和 erase
		vector<int> v;
		v.push_back(1);
		v.push_back(2);
		v.push_back(3);
		v.push_back(4);
		v.push_back(5);


		for (size_t i = 0; i < v.size(); ++i)
		{
			cout << v[i] << " ";
		}
		cout << endl;

		v.insert(v.end(), 6);
		for (size_t i = 0; i < v.size(); ++i)
		{
			cout << v[i] << " ";
		}
		cout << endl;

		v.erase(v.end() - 1);
		for (size_t i = 0; i < v.size(); ++i)
		{
			cout << v[i] << " ";
		}
		cout << endl;

		v.erase(v.begin());
		for (size_t i = 0; i < v.size(); ++i)
		{
			cout << v[i] << " ";
		}
		cout << endl;
	}




	void test_vector2()
	{
		vector<int> v;
		v.push_back(1);
		v.push_back(2);
		v.push_back(3);
		v.push_back(4);

		for (auto e:v)
		{
			cout<< e <<" ";
		}
		cout << endl;

		auto p = find(v.begin(),v.end(),3); //支持了迭代器,就支持了stl里面的find
		if (p != v.end())
		{
			v.insert(p,30); //当需要在pos位置插入数据时,遇到了vector需要扩容的情况;注意在扩容之后,pos已经失效了(因为pos是指向原来数组中的某个位置,现在数组直接销毁了)
		}

		for (auto e : v)
		{
			cout << e << " ";
		}
		cout << endl;

	}




	void test_vector3()
	{
		vector<int> v;
		v.push_back(1);
		v.push_back(2);
		v.push_back(3);
		v.push_back(4);
		v.push_back(5);

		for (auto e:v)
		{
			cout<< e <<" ";
		}
		cout << endl;

		auto p = find(v.begin(),v.end(),3);
		if (p != v.end())
		{
			v.erase(p);
		}

		for (auto e:v)
		{
			cout<< e <<" ";
		}
		cout << endl;
	}



	void test_vector4()
	{
		//情况1:运行正常——运气好
		vector<int> v;
		v.push_back(1);
		v.push_back(2);
		v.push_back(3);
		v.push_back(4);


		//要求删除所有的偶数
		auto it = v.begin();
		while (it != v.end())
		{
			//没有更新迭代器的代码是:
			/*if (*it % 2==0)
			{
				v.erase(it);
			}
			++it;*/

			//有迭代器更新的代码:
			if (*it % 2 == 0)
			{
				it = v.erase(it); //要更新迭代器,也就是pos的位置
			}
			else
			{
				++it;
			}
		}

		for (auto e : v)
		{
			cout << e << " ";
		}
		cout << endl;

	}
	//结论: insert/erase pos位置,不要直接访问pos。一定要更新,直接访问可能会导致各种出乎意料的结果,这就是所谓的迭代器失效。
	//【要认为pos失效了,不要访问】
	

}

Test.cpp

#include <iostream>
using namespace std;
#include "vector.h"

int main()
{
	
	JPC::test_vector4();

	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值