(第一步) STL: stl_vector容器实现

简略版:https://blog.csdn.net/qq_38223012/article/details/119278445

可以实现基本功能

这是完整版,扩展后学习的

stl_vector.h

#pragma once
#ifndef _STL_VECTOR_H_
#define _STL_VECTOR_H_

#include "../Includes/TypeTraits.h"
#include "../Includes/Algorithm.h"

#include "../Includes/Iterator.h"
#include "../Includes/ReverseIterator.h"
#include "../Includes/UninitializedFunctions.h"
#include "../Includes/Allocator.h"


namespace mySTL {
	template<class T, class alloc = allocator<T>>
	class vector {
	
	public:
		// vector的嵌套型别定义			 
		typedef T	value_type;				// 元素类型
		typedef T* pointer;					// 指针类型
		typedef T* iterator;				// vector是线性空间,所以iterator普通指针
		typedef const T& const_reference;
		typedef T& reference;				// 重构相关的左引用,引用类型
		typedef size_t size_type;			// 用于指明数组长度,它必须是一个正数
		typedef ptrdiff_t difference_type;	// 应保证足以存放同一数组中两个指针之间的差距,它有可能是负数。

	private:

		iterator start;				//目前使用空间的开头
		iterator finish;			//目前使用空间的结尾
		iterator endOfStorage;		//目前可用空间的尾部

		typedef alloc dataAllocator;
		
	public:
		//构造函数												// 构造类型
		vector(): start(0), finish(0), endOfStorage(0){}		// vector<int> vec;
		//explicit防止类构造函数的隐式自动转换.				    //
		explicit vector(const size_type n);						// vector<int> vec(10);
		vector(const size_type n, const value_type& val);		// vector<int> vec(10, 1);

		// 拷贝构造函数
		template<class InputIterator>
		vector(InputIterator first, InputIterator last);
		vector(const vector& v);
		vector(vector&& v);
		vector& operator = (const vector& v);
		vector& operator = (vector&& v);

		//析构函数
		~vector();

		bool operator == (const vector& v)const;
		bool operator != (const vector& v)const;

	public:
		// 迭代器相关函数
		iterator begin() { return start; }
		iterator end() { return finish; }

		// 容量相关函数
		size_type size() const { return finish - start; }				
		size_type capacity() const { return endOfStorage - start; }		
		bool empty() const { return start == finish; }
		void resize(size_type n, value_type val = value_type());

		// 访问元素相关
		reference operator[](const size_type i) { return *(begin() + i); }
		reference front() { return *(begin()); }
		reference back() { return *(end() - 1); }

		// 修改容器相关的操作
		// 清空容器,销毁容器中的所有对象并使容器的size为0,但不回收容器已有的空间
		void clear();
		void push_back(const value_type& val);
		void pop_back();
		iterator erase(iterator position);
		iterator insert(iterator position, const value_type& val);
		void insert(iterator position, const size_type& n, const value_type& val);
		template <class InputIterator>
		void insert(iterator position, InputIterator first, InputIterator last);

		void swap(vector& v);
		iterator erase(iterator first, iterator last);


		// 容器的空间配置器相关
		alloc get_allocator() { return dataAllocator; }

	private:
		void destroyAndDeallocate();										// 析构并释放空间
		void allocateAndFill(const size_type n, const value_type& val);		// 分配空间并填充数值val
		template<class InputIterator>
		void reallocateAndCopy(iterator position, InputIterator first, InputIterator last);
		void reallocateAndFill(iterator position, const size_type& n, const value_type& val);
		size_type getNewCapacity(size_type len)const;

		template<class InputIterator>
		void allocateAndCopy(InputIterator first, InputIterator last);

		// insert辅助函数
		template<class InputIterator>										// 判断是否内存够用,重新分配内存为原来的2倍
		void insert_aux(iterator position, InputIterator first, InputIterator last, std::false_type);
		template<class Integer>
		void insert_aux(iterator position, Integer n, const value_type& value, std::true_type);
		
		// 拷贝构造的辅助函数
		template<class InputIterator>
		void vector_aux(InputIterator first, InputIterator last, std::false_type);
		template<class Integer>
		void vector_aux(Integer n, const value_type& value, std::true_type);
		
	public:
		template<class T, class Alloc>
		friend bool operator == (const vector<T, Alloc>& v1, const vector<T, Alloc>& v2);
		template<class T, class Alloc>
		friend bool operator != (const vector<T, Alloc>& v1, const vector<T, Alloc>& v2);


	};



}

#include "../Detail/stl_vector.impl.h"
#endif

stl_vector.impl.h

#include "..\p2_STL_Source\stl_vector.h"
#pragma once

namespace mySTL {
	//***********************构造,析构相关***********************
	//构造函数	
	template<class T, class alloc>
	vector<T, alloc>::vector(const size_type n)
	{
		allocateAndFill(n, value_type());
	}

	template<class T, class alloc>
	vector<T, alloc>::vector(const size_type n, const value_type& val)
	{
		allocateAndFill(n, val);
	}


	

	//析构函数
	template<class T, class alloc>	
	vector<T, alloc>::~vector()
	{
		destroyAndDeallocate();
	}

	//***********逻辑比较操作相关*******************
	template<class T, class alloc>
	bool vector<T, alloc>::operator == (const vector& v)const {
		if (size() != v.size()) {
			return false;
		}
		else {
			auto ptr1 = start;
			auto ptr2 = v.start;
			for (; ptr1 != finish && ptr2 != v.finish; ++ptr1, ++ptr2) {
				if (*ptr1 != *ptr2)
					return false;
			}
			return true;
		}
	}
	template<class T, class alloc>
	bool vector<T, alloc>::operator != (const vector& v)const {
		return !(*this == v);
	}

	//*************和容器的容量相关******************************
	template<class T, class alloc>
	void vector<T, alloc>::resize(size_type n, value_type val)
	{
		if (n < size())
		{
			dataAllocator::destroy(start + n, finish);
			finish = start + n;
		}
		else if (n > size() && n <= capacity())
		{
			auto lengthOfInsert = n - size();
			//局部初始化,底层通过memset初始化,返回填充结束的尾部地址
			finish = mySTL::uninitialized_fill_n(finish, lengthOfInsert, val); 
		}
		else if (n > capacity())
		{
			auto lengthOfInsert = n - size();
			// 以上三步为走
			// 第一步,获取扩容大小,并返回扩容后总的大小,进行新的内存分配
			// 第二步,copy当前vector数据,填充到新地址中, end指向原理容量大小的位置,
			// 第三步,将扩充部分进行数据填充,end指向扩容后的尾部
			T* newStart = dataAllocator::allocate(getNewCapacity(lengthOfInsert));
			// 数据拷贝,底层通过memcopy实现,返回当前大小的尾部地址
			T* newFinish = mySTL::uninitialized_copy(begin(), end(), newStart);
			newFinish = mySTL::uninitialized_fill_n(newFinish, lengthOfInsert, val);
			

			destroyAndDeallocate();

			// 更新容器参数
			start = newStart;
			finish = newFinish;
			endOfStorage = start + n;
		}
	}

	//***************修改容器的相关操作**************************
	template<class T, class alloc>
	void vector<T, alloc>::clear()
	{
		dataAllocator::destroy(start, finish);
		finish = start;
	}

	template<class T, class alloc>
	void vector<T, alloc>::push_back(const value_type& val)
	{
		insert(end(), val);
	}

	template<class T, class alloc>
	void vector<T, alloc>::pop_back()
	{
		--finish;
		dataAllocator::destroy(finish);
	}

	// 清除某位置上元素
	template<class T, class alloc>
	typename vector<T, alloc>::iterator vector<T, alloc>::erase(iterator position)
	{
		return erase(position, position + 1);
	}

	template<class T, class alloc>
	typename vector<T, alloc>::iterator vector<T, alloc>::erase(iterator first, iterator last) 
	{
		//尾部残留对象数
		difference_type lenOfTail = end() - last;
		//删去的对象数目
		difference_type lenOfRemoved = last - first;

		finish = finish - lenOfRemoved;
		// 向前移动 lenOfRemoved距离
		for (; lenOfTail != 0; --lenOfTail)
		{
			auto temp = (last - lenOfRemoved);
			*temp = *(last++);
		}

		return first;
	}

	template<class T, class alloc>
	void vector<T, alloc>::swap(vector& v) {
		if (this != &v) {
			mySTL::swap(start, v.start);
			mySTL::swap(finish, v.finish);
			mySTL::swap(endOfStorage, v.endOfStorage);
		}
	}

	/********************* insert 函数实现解析 ************/


	template<class T, class alloc>
	typename vector<T, alloc>::iterator vector<T, alloc>::insert(iterator position, const value_type& val)
	{
		const auto index = position - begin();
		insert(position, 1, val);

		return begin() + index;
	}

	template<class T, class Alloc>
	template<class InputIterator>
	void vector<T, Alloc>::insert(iterator position, InputIterator first, InputIterator last) {
		insert_aux(position, first, last, typename std::is_integral<InputIterator>::type());
	}

	template<class T, class alloc>
	void vector<T, alloc>::insert(iterator position, const size_type& n, const value_type& val)
	{
		insert_aux(position, n, val, typename std::is_integral<size_type>::type());	
		// std::is_integral<size_type>判断是否是int类型,是完成插入功能,不是终止,没有写string等类型的
	}

	template<class T, class alloc>
	template<class InputIterator>
	typename void vector<T, alloc>::insert_aux(iterator position, InputIterator first, InputIterator last, std::false_type)
	{
		difference_type locationLeft = endOfStorage - finish; // the size of left storage
		difference_type locationNeed = distance(first, last);//last - first;

		if (locationLeft >= locationNeed) {
			if (finish - position > locationNeed) {
				mySTL::uninitialized_copy(finish - locationNeed, finish, finish);
				std::copy_backward(position, finish - locationNeed, finish);
				std::copy(first, last, position);
			}
			else {
				iterator temp = mySTL::uninitialized_copy(first + (finish - position), last, finish);
				mySTL::uninitialized_copy(position, finish, temp);
				std::copy(first, first + (finish - position), position);
			}
			finish += locationNeed;
		}
		else {
			reallocateAndCopy(position, first, last);
		}
	}

	template<class T, class alloc>
	template<class Integer>
	typename void vector<T, alloc>::insert_aux(iterator position, Integer n, const value_type& value, std::true_type)
	{
		//其作用是如果它的条件返回错误,则终止程序执行。
		assert(n != 0);

		difference_type locationLeft = endOfStorage - finish;	// 未使用空间大小
		difference_type locationNeed = n;

		if (locationLeft >= locationNeed)						// 当前容器满足插入空间大小
		{
			auto tempPtr = end() - 1;

			for (; tempPtr - position >= 0; --tempPtr)
			{
				// placement new,就是在指针p所指向的内存空间创建一个T1类型的对象,
				// 但是对象的内容是从T2类型的对象转换过来的(调用了T1的构造函数,T1::T1(value))。
				// 就是在已有空间的基础上重新调整分配的空间
				construct(tempPtr + locationNeed, *tempPtr);	
			}

			mySTL::uninitialized_fill_n(position, n, value);

			finish += locationNeed;
		}
		else
		{
			reallocateAndFill(position, n, value);
		}


	}

	/********************* insert 函数解析结束 ************/

	// 容器的空间配置器相关

	/********************* 扩展内存大小, 并返回新的大小 ************/
	template<class T, class alloc>
	typename vector<T, alloc>::size_type vector<T, alloc>::getNewCapacity(size_type len)const{
		size_type oldCapacity = endOfStorage - start;  // 旧容器的容量

		auto res = mySTL::max(oldCapacity, len);		// 容器容量扩展量,选择大的

		// 新容器的容量
		// 如果未定义,则选择resize所定的,
		// 如果定义了,容量*2,或者更大容量 + len(此时len比旧容量大)
		size_type newCapacity = (oldCapacity != 0 ? (oldCapacity + res) : len); 

		return newCapacity;
	}

	template<class T, class alloc>
	void vector<T, alloc>::destroyAndDeallocate()
	{
		if (capacity() != 0)
		{
			// destory负责调用类型的析构函数,销毁相应内存上的内容(但销毁后内存地址仍保留)
			// deallocate负责释放内存,在此之前应调用destory销毁,将内存地址返回给系统
			dataAllocator::destroy(start, finish);
			dataAllocator::deallocate(start, capacity());
		}
	}

	template<class T, class alloc>
	typename void vector<T, alloc>::allocateAndFill(const size_type n, const value_type& val)
	{
		start = dataAllocator::allocate(n);
		mySTL::uninitialized_fill_n(start, n, val);
		finish = endOfStorage = start + n;

	}

	template<class T, class alloc>
	template<class InputIterator>
	void vector<T, alloc>::reallocateAndCopy(iterator position, InputIterator first, InputIterator last)
	{
		difference_type newCapacity = getNewCapacity(last - first);

		T* newStart = dataAllocator::allocate(newCapacity);
		T* newEndOfStorage = newStart + newCapacity;
		T* newFinish = mySTL::uninitialized_copy(begin(), position, newStart);
		newFinish = mySTL::uninitialized_copy(first, last, newFinish);
		newFinish = mySTL::uninitialized_copy(position, end(), newFinish);

		destroyAndDeallocate();
		start = newStart;
		finish = newFinish;
		endOfStorage = newEndOfStorage;
	}

	

	template<class T, class alloc>
	void vector<T, alloc>::reallocateAndFill(iterator position, const size_type& n, const value_type& val)
	{
		difference_type newCapcity = getNewCapacity(n);

		T* newStart = dataAllocator::allocate(newCapcity);
		T* newEndOfStorage = newStart + newCapcity;
		T* newFinish = mySTL::uninitialized_copy(begin(), position, newStart);
		newFinish = mySTL::uninitialized_fill_n(newFinish, n, val);
		newFinish = mySTL::uninitialized_copy(position, end(), newFinish);

		destroyAndDeallocate();

		start = newStart;
		finish = newFinish;
		endOfStorage = newEndOfStorage;
	}

	/*************************丰富功能************************/ 
	// 拷贝构造函数
	template<class T, class alloc>
	template<class InputIterator>
	inline vector<T, alloc>::vector(InputIterator first, InputIterator last)
	{
		vector_aux(first, last, typename std::is_integral<InputIterator>::type());
	}

	template<class T, class alloc>
	vector<T, alloc>::vector(const vector& v) {
		allocateAndCopy(v.start, v.finish);
	}

	template<class T, class alloc>
	vector<T, alloc>::vector(vector&& v) {
		start = v.start;
		finish = v.finish;
		endOfStorage = v.endOfStorage;
		v.start = v.finish = v.endOfStorage = 0;
	}
	
	template<class T, class alloc>
	vector<T, alloc>& vector<T, alloc>::operator = (const vector& v) {
		if (this != &v) {
			allocateAndCopy(v.start, v.finish);
		}
		return *this;
	}
	template<class T, class alloc>
	vector<T, alloc>& vector<T, alloc>::operator = (vector&& v) {
		if (this != &v) {
			destroyAndDeallocate();
			start = v.start;
			finish = v.finish;
			endOfStorage = v.endOfStorage;
			v.start = v.finish = v.endOfStorage = 0;
		}
		return *this;
	}

	template<class T, class alloc>
	template<class InputIterator>
	inline void mySTL::vector<T, alloc>::allocateAndCopy(InputIterator first, InputIterator last)
	{
		start = dataAllocator::allocate(last - first);
		finish = mySTL::uninitialized_copy(first, last, start);
		endOfStorage = finish;
	}

	template<class T, class alloc>
	template<class InputIterator>
	void vector<T, alloc>::vector_aux(InputIterator first, InputIterator last, std::false_type) {
		allocateAndCopy(first, last);
	}
	template<class T, class alloc>
	template<class Integer>
	void vector<T, alloc>::vector_aux(Integer n, const value_type& value, std::true_type) {
		allocateAndFill(n, value);
	}

	
	template<class T, class alloc>
	bool operator == (const vector<T, alloc>& v1, const vector<T, alloc>& v2) {
		//return v1 == v2;
		return v1.operator==(v2);
	}
	template<class T, class alloc>
	bool operator != (const vector<T, alloc>& v1, const vector<T, alloc>& v2) {
		return !(v1 == v2);
	}

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值