简单模拟实现STL--vector

模拟实现STL--vector:

代码分为两块

  • 1、std::vector的核心框架接口的模拟实现 lxy::vector
  • 2、对lxy::vector核心接口的测试

重点注意----迭代器失效场景总结:

1、删除pos迭代器位置所指向的元素没有及时给pos赋值。比如:v.erase(pos)

2、可能会引起vector底层空间改变的操作。比如:push_back();   insert();   resize();   reserve()

代码实现:


//模拟实现vector
//vector----可以存放任意类型的动态顺序表
#include<iostream>
#include<assert.h>

using namespace std;

namespace lxy    //自定义一个命名空间
{
	template<class T>   //写成模板形式,以供多个类型使用
	class vector
	{
	public:
		//vector 的迭代器实际上就是原生态的指针
		typedef T* iterator;
	public:
		/////////////////////////////////////////////////////////
		//构造与销毁
		vector()      //无参构造
			:_start(nullptr)
			,_finish(nullptr)
			,_endofstorage(nullptr)
		{}

		vector(int n, const T& data)
			:_start(new T[n])
		{
			for (size_t i = 0; i < n; ++i)
			{
				_start[i] = data;				
			}
			_finish = _start + n;
			_endofstorage = _finish;
		}

		//[first,last)区间构造
		template<class Iterator>
		vector(Iterator first, iterator last)
		{
			//计算区间之间的元素个数
			size_t n = 0;
			auto it = first;
			while (it != last)
			{
				++it;
				++n;
			}
			_start = new T[n];
			//将[first,last)区间中的元素放置到_start的空间中
			for (size_t i = 0; i < n; ++i)
			{
				_start[i] = *first++;
			}
			_finish = _start + n;
			_endofstorage = _finish;
		}

		vector(const vector<T>& vv)    //拷贝构造
			:_start(new T[vv.capacity()])    //为构造对象申请空间
		{
			//拷贝内容:深拷贝,不能使用memcpy(),避免二次释放的情况发生
			for (size_t i = 0; i < vv.size(); ++i)
			{
				_start[i] = vv[i];
			}
			_finish = _start + vv.size();
			_endofstorage = _start + vv.capacity();
		}

		void Swap(vector<T> v)
		{
			swap(_start, v._start);
			swap(_finish, v._finish);
			swap(_endofstorage, v._endofstorage);
		}

		vector<T>& operator=(const vector<T>& v)
		{
			Swap(v);
			return *this;
		}

		~vector()    //析构函数
		{
			if (_start)     //如果不为空
			{
				delete[] _start;    //销毁空间
				_start = _finish = _endofstorage = nullptr;    //释放指针
			}
		}


		/////////////////////////////////////////////////////////
		//容量操作
		size_t size()const
		{
			return _finish - _start;
		}

		size_t capacity()const
		{
			return _endofstorage - _start;
		}

		bool emoty()const
		{
			return _start == _finish;
		}

		//T():
		//如果T代表内置类型,T()----0
		//如果T代表自定义类型,T()----调用该类无参构造函数
		void resize(size_t newsize, const T&data = T())
		{
			size_t oldsize = size();
			if (newsize > oldsize)
			{
				size_t cap = capacity();
				if (newsize > cap)
				{
					reserve(newsize);
				}
				for (; oldsize < newsize; ++oldsize)
				{
					_start[oldsize] = data;
				}
			}
			_finish = _start + newsize;
		}

		void reserve(size_t newcapacity)
		{
			size_t oldcapacity = capacity();
			if (newcapacity > oldcapacity)
			{
				//1、申请新空间
				T* temp = new T[newcapacity];
				//2、拷贝元素
				//mencpy(temp, _start, size(*sizeof(T)));    //不推荐使用此方法,应该使用深拷贝,避免二次释放的情况发生
				size_t n = size();
				if (_start)
				{
					for (size_t i = 0; i < n; ++i)
					{
						temp[i] = _start[i];
					}
					//3、释放旧空间
					delete[] _start;
				}
				_start = temp;
				_finish = _start + n;
				_endofstorage = _start + newcapacity;
			}
		}

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


		/////////////////////////////////////////////////////////
		//元素访问操作  (大多都是成对存在)
		//v[0] = 10;   //v如果是普通类型
		T& operator[](size_t index)
		{
			assert(index < size());
			return _start[index];
		}
		const T& operator[](size_t index)const
		{
			assert(index < size());
			return _start[index];
		}

		T& front()
		{
			return *_start;
		}
		const T& front()const
		{
			return *_start;
		}

		T& back()
		{
			return *(_finish - 1);//这里最好不要使用_finish--,否则会修改_finish的位置
		}
		const T& back()const
		{
			return *(_finish - 1);
		}

		///////////////////////////////////////////////////////////
		//元素修改
		//时间复杂度O(1)
		void push_back(const T& data)
		{
			//插入之前检测是否需要扩容
			if (_finish == _endofstorage)
			{
				reserve(capacity() * 2 + 3);  //*2  默认假设每次扩容到两倍,+3  是为了防止原本capacity()为0
			}
			*_finish++ = data;   
		}

		void pop_back()
		{
			--_finish;
		}

		//返回值含义:返回新插入元素的位置
		iterator insert(iterator pos, const T& data)
		{
			//插入之前检测是否需要扩容
			if (_finish == _endofstorage)
			{
				reserve(capacity() * 2 + 3);  //*2  默认假设每次扩容到两倍,+3  是为了防止原本capacity()为0
			}
			//将[pos,_finish)之间的元素整体向后搬移一个位置
			auto it = _finish;
			while (it > pos)
			{
				*it = *(it - 1);
				it--;
			}
			//插入新元素
			*pos = data;
			++_finish;
			return pos;
		}

		iterator erase(iterator pos)
		{
			//判空
			if (pos == end())
			{
				return pos;
			}
			//it代表待搬移元素的位置
			auto it = pos + 1;
			while (it != _finish)
			{
				*(it - 1) = *it;
				++it;
			}
			--_finish;
			return pos;
		}

		void clear()
		{
			_finish = _start;
		}
	private:
		T* _start;
		T* _finish;
		T* _endofstorage;
	};
}


void Test1()
{
	lxy::vector<int> v1;
	lxy::vector<int> v2(10, 5);
	lxy::vector<int> v4(v2);
	lxy::vector<int> v5 = v2;

	int array[] = { 0, 2, 4, 6, 8 };
	lxy::vector<int> v3(array, array + sizeof(array) / sizeof(array[0]));

	cout << v2.size() << endl;
	cout << v2.capacity() << endl;
	cout << v3.front() << endl;
	cout << v3.back() << endl;

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

	//lxy::vector<int>::iterator it = v3.begin(); 
	auto it = v3.begin();
	while (it != v3.end())
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;

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


void Test2()
{
	lxy::vector<int> v;
	v.push_back(1);
	v.push_back(3);
	v.push_back(6);
	v.push_back(9);

	cout << v.size() << endl;
	cout << v.capacity() << endl;
	cout << v.back() << endl;

	v.pop_back();
	cout << v.back() << endl;
	cout << v.size() << endl;

	cout << v.front() << endl;
	v.insert(v.begin(), 0);
	cout << v.front() << endl;
	cout << v.size() << endl;
}


void Test3()
{
	lxy::vector<int> v(10, 5);
	cout << v.size() << endl;
	cout << v.capacity() << endl;

	v.resize(5);
	cout << v.size() << endl;
	cout << v.capacity() << endl;

	v.resize(8);
	cout << v.size() << endl;
	cout << v.capacity() << endl;

	v.resize(20,5);
	cout << v.size() << endl;
	cout << v.capacity() << endl;

}

int main()
{
	Test1();
	//Test2();
	//Test3();
	return 0;
}
发布了83 篇原创文章 · 获赞 26 · 访问量 8708

猜你喜欢

转载自blog.csdn.net/lexiaoyao_0000/article/details/102507910
今日推荐