vector 的学习

#pragma once

#include


namespace chen
{


  template
  class vector
  {

	public:	
		typedef T* iterator;
		//const 迭代器
		typedef const T* const_iterator; //只是指向的内容不能修改 迭代器本身可以++

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

		iterator end()
		{
			return _finish;
		}

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

		const_iterator end() cosnt
		{
			return _finish;
		}


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

		}

		//类模版里面也可以继续写模版函数-----------迭代器区间初始化
		template
		vector(InputIterator first, InputIterator last)
		{
			while (first != last)
			{
				push_back(*first);
				++first;
			}
		}

		//用 n 个 val 去初始化
		vector(size_t n, const T val = T())
		{
			reserve(n);
			for (size_t i = 0; i < n; i++)
			{
				push_back(val);

			}
		}

		vector(int n, const T& val = T())
		{
			reserve(n);
			for (size_t i = 0; i < n; i++)
			{
				push_back(val);

			}
		}



		//拷贝构造
		vector(const vector& v)
			:_start(nullptr)
			,_finish(nullptr)
			,_endofstorage(nullptr)
		{
			reserve(v.capacity());
			for (auto e : v)
			{
				push_back(e);
			}
		}


		//运算符重载 =

		void swap(vector& v)
		{
			std::swap(_start, v._start);
			std::swap(_finish, v._finish);
			std::swap(_endofstorage, v._endofstorage);

		}

		vector& operator=(vector tmp)
		{
			swap(tmp);
			return *this;
		}


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


		//扩容 reserve
		void reserve(size_t n)
		{
			if (n > capacity())
			{
				size_t sz = size();
				T* tmp = new T[n]; //开新的空间
				if (_strat)
				{
					//这种方式有坑是浅拷贝
					//memcpy(tmp, _str, sizeof(T) * sz);//如果旧空间有值的话就把旧空间的值拷贝到新的空间 并把旧空间释放掉
					//我们换一种方式
					for (size_t i = 0; i < sz; i++)
					{
						tmp[i] = _start[i]; // 赋值会调用拷贝构造
					}
					
					delete[] _start;
				}

				_start = tmp;
				_finish = _start + sz;
				_endofstorage = _start + n;
			}
		}


		//resize 的实现  注意看这里的缺省值没有给零,因为你不知道给的类型是什么,如果是int那你可以给0,如果是string类呢,你给个0合适吗?
		//所以这里给了一个T类型的匿名对象 这样就会去调用它的默认构造函数来生成一个对象 这里先构造在拷贝构造编译器会优化成直接构造
		//这里相当于创建了一个匿名对象去引用它,const 引用会延长匿名对象的生命周期 延长到val不用的时候
		//这里也不能不加const 因为匿名对象和临时对象具有常性,所以必须加上 const
		//还需要注意的是:你可以认为在模版出来以后,内置类型也有构造函数了,所以下面这样写也对int同样适用
		void resize(size_t n, const T& val = T())
		{
			if (n < size())
			{
				_finish = _start + n;
			}
			else
			{
				reserve(n);
				while(_finish < _start + n)
				{
					*_finish = val;
					++finish;
				}
			}
		}

		//尾插
		void push_back(const T& x)
		{
			//检查是否需要扩容
			//if (_finish == _endofstorage)
			//{
			//	size_t sz = size();
			//	size_t cp = capacity() == 0 ? 4 : capacity() * 2;
			//
			//	T* tmp = new T[cp]; //new如果失败的话是会抛异常的

			//	if (_start)//如果原来的空间不为空,你要将原来空间的值放入新的空间中
			//	{
			//		memcpy(tmp, _start, sizeof(T) * sz);
			//		delete[] _start; 
			//	}
			//	_start = tmp;
			//	_finish = _start + sz;
			//	
			//	_endofstorage = _start + cp;
	        //}


			if (_finish == _endofstorage)
			{
				reserve(capacity() == 0 ? 4 : capacity() * 2);
			}

			//开始尾插
			*_finish = x;
			++_finish;
 
		}

		插入 -------------迭代器失效的第一种场景:野指针,扩容之后pos还在原来的位置,变成野指针了
		//void insert(iterator pos, const T& x)
		//{
		//	assert(pos >= _start);
		//	assert(pos <= _finish);

		//	if (_finish == _endofstorage)
		//	{
		//		reserve(capacity() == 0 ? 4 : capacity() * 2);
		//	}

		//	iterator end = _finish - 1;
		//	while (end >= pos)
		//	{
		//		*(end + 1) = *end;
		//		end--;
		//	}
		//	*pos = x;
		//	++_finish;
		//}


		//插入 ——————改进 注意:我们一般认为使用了insert插入后 it就失效了,不能访问了
		void insert(iterator pos, const T& x)
		{
			assert(pos >= _start); 
			assert(pos <= _finish);

			if (_finish == _endofstorage)
			{
				size_t len = pos - _start; //记录相对长度
				reserve(capacity() == 0 ? 4 : capacity() * 2);
				pos = _start + len; //找到新的位置 
			}

			iterator end = _finish - 1;
			while (end >= pos)
			{
				*(end + 1) = *end;
				end--;
			}
			*pos = x;
			++_finish;
		}




		//删除------------erase之后的pos也失效了(迭代器失效了)
		iterator erase(iterator pos)            //insert 和 erase 以后迭代器都失效了 
		{
			assert(pos >= _start)
				assert(pos < _finish)

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

		//运算符重载 []
		T& operator[](size_t pos)
		{
			assert(pos < size());

			return _start[pos];
		}

		//运算符重载 [] const
		const T& operator[](size_t pos) const
		{
			assert(pos < size());

			return _start[pos];
		}


		//返回容量
		size_t capacity() const
		{
			return _endofstorage - _start;
		}

		//返回元素个数
		size_t size() const
		{
			return _finish - _start;
		}

	private:
		iterator _start;
		iterator _finish;
		iterator _endofstorage;
  };



}

你可能感兴趣的:(c++)