【数据结构】模拟实现Vecotr

cpp 复制代码
namespace my_vector
{

	template <class T>
	class vector
	{
	public:
		typedef T* iterator;
		typedef const T* const_iterator;//常量指针,指针指向的值不可以变;
        
		//构造函数
		vector()
			:start(nullptr)
			,finish(nullptr)
			,end_of_storage(nullptr)
		{
		    

		}
		//析构函数
		~vector()
		{
			delete[] start;
			start = finish = end_of_storage = nullptr;	
		}

		

		//const T& x=T();   这个的生命周期从一行被延长为当前作用域结束;无论是内置类型还是自定义类型都可以采用匿名形式
		vector(int n,const T& val=T())
			:start(nullptr)
			, finish(nullptr)
			, end_of_storage(nullptr)
		{
		
			for (int i=0;i<n;++i)
			{
				push_back(val);
			}

		}

//迭代器构造函数,即便是string类的迭代器也能拷贝,只是把char类型转成int(打比方)类型,所以会造成空间浪费;
//不同类型的迭代器拷贝可能引起数据丢失和越界问题或者浪费空间等问题);
		//模板   
		template<class InputIterator>
		vector(InputIterator first,InputIterator last)
		{
			while (first!=last)
			{
				//vs库里面的迭代器不是原生指针,而是被封装好的类;
				push_back(*first);//这里不能用自定义类型会出现"非法寻址"的问题
				++first;
			}
		 
		}

		//拷贝构造函数
		vector(const vector<T>& v)
		{
			reserve(v.capacity());
			//浅拷贝:memcpy(start,v.start,sizeof(t)*v.size());
			
			//深拷贝
			for(int i=0;i<v.size();++i)
			{
				start[i] = v.start[i];//里面如果是自定义类型,会调用赋值函数构造每一个对象(会自己开辟空间,在下面90行已经实现深层赋值,针对vector<t>)属于深拷贝;
			}
			finish = start + v.size();
			end_of_storage = start + v.capacity();
		}

		vector(initializer_list<T> i1)
		{
			//常量数组结构体对象
			initializer_list<T> ::iterator it = i1.begin();
			while (it!=i1.end())
			{
				push_back(*it);
				++it;
			}
		
		}

		void swap(vector<T>& v)
		{
			std::swap(start,v.start);
			std::swap(finish, v.finish);
			std::swap(end_of_storage, v.end_of_storage);		
		}

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

		void reserve(size_t n)  
		{
			//需要的空间大于原容量才进行扩容
			if (n > capacity())
			{
				T* tmp = new T[n];
				size_t sz = size();
				if (start)//如果原来的空间不为空,那么就直接拷贝原来所有的元素(如果是自定义类型,会两次析构);
				{
					//memcpy(tmp,start,sizeof(T)*size());
					for (int i=0;i<size();++i)
					{
						tmp[i] = start[i];//深拷贝
					}
					delete[] start;
				}

				start = tmp;
				finish = tmp + sz;
				end_of_storage = tmp + n;
			}
		
		
		}
		//扩容+初始化
		void resize(size_t n,T val=T())
		{ 
			if (n>capacity())
			{
				reserve(n);
				while (finish!=end_of_storage)
				{
					*finish = val;
					++finish;
				}

			}
			else
			{

				if (n < size())
				{
					//删除数据
					finish = start + n;
				}

			}
		}

		//迭代器失效问题:野指针(扩容引起)
		iterator insert(iterator pos,const T& val)
		{
			assert(pos<=finish);
			assert(pos>=start);

			
			//判断是否需要扩容
			if (finish==end_of_storage)
			{    
				int len = pos - start;
				size_t newCapacity = capacity() == 0 ? 4 : capacity() * 2;
				reserve(newCapacity);
				//扩容会导致pos迭代器失效,需要更新一下;
				pos = start + len;
			}

			iterator end = finish - 1;
			while (end>=pos)
			{
				*(end+1) = *end;
				--end;
			}
			*pos = val;
			++finish;
			return pos;//返回更改后的形参pos,让pos指向插入的元素,也就是原来指向的前一个;
		}


		iterator erase(iterator pos)
		{
			assert(pos <finish);
			assert(pos >= start);
            
			iterator end = pos+1;
     		while (end<finish)
			{
				*(end - 1) = *end;
				++end;
			}
			--finish;
			return pos;
		}

		void push_back(const T& x)
		{
			if (finish==end_of_storage)
			{
				reserve(capacity()==0?4:capacity()*2);             
			}
			*finish = x;
			++finish;
		}
	    
		void pop_back()
		{
			assert(!empty());
			--finish;
		}

		bool empty()
		{
			return start == finish;
		}

		T& operator[](size_t pos)//无符号整数pos,如果pos为-1,那么就是int型正整数的最大值;
		{
			assert(pos < size());
			return *(start + pos);
		}

		 T& operator[](size_t pos)const//无符号整数pos,如果pos为-1,那么就是int型正整数的最大值;
		{
			assert(pos < size());
			return *(start + pos);
		}
		

        //迭代器不要引用返回,因为如果++或--迭代器,vector容器里面也会更改;
		iterator begin() 
		{
			return start;
		}

		const_iterator begin()const
		{
			return start;
		}

		iterator end() 
		{
			return finish;
		}
		const_iterator end()const
		{
			return finish;
		}
		const size_t size() const
		{
			return finish - start;
		}

		const size_t capacity() const
		{
			return end_of_storage - start;
		}

	private:
		iterator start;
		iterator finish;
		iterator end_of_storage;
	};
}
相关推荐
霁月风13 分钟前
设计模式——适配器模式
c++·适配器模式
sp_fyf_202415 分钟前
计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-11-01
人工智能·深度学习·神经网络·算法·机器学习·语言模型·数据挖掘
ChoSeitaku34 分钟前
链表交集相关算法题|AB链表公共元素生成链表C|AB链表交集存放于A|连续子序列|相交链表求交点位置(C)
数据结构·考研·链表
偷心编程35 分钟前
双向链表专题
数据结构
香菜大丸35 分钟前
链表的归并排序
数据结构·算法·链表
jrrz082835 分钟前
LeetCode 热题100(七)【链表】(1)
数据结构·c++·算法·leetcode·链表
oliveira-time1 小时前
golang学习2
算法
咖啡里的茶i1 小时前
Vehicle友元Date多态Sedan和Truck
c++
海绵波波1071 小时前
Webserver(4.9)本地套接字的通信
c++
@小博的博客1 小时前
C++初阶学习第十弹——深入讲解vector的迭代器失效
数据结构·c++·学习