当前位置 博文首页 > Scissors_初夏的博客:初夏小谈:vector的模拟实现(二)解决浅

    Scissors_初夏的博客:初夏小谈:vector的模拟实现(二)解决浅

    作者:[db:作者] 时间:2021-08-28 13:10

    上次实现的vector中存在这样的问题:就是在扩容中用memcpy来进行元素的拷贝,但是它会拷贝数据的位置,到另一块空间中。这样在后面的释放原来的空间后,这一份资源就会被释放,从而这块新空间指向的资源将会失效。程序就会发生崩溃。所以就进行深拷贝。

    代码如下:

    #include<iostream>
    #include<vector>
    using namespace std;
    
    namespace FirstVector
    {
    	template<class T>
    	class vector
    	{
    	public:
    		typedef T* iterator;
    		typedef T* reverse_iterator;
    	public:
    		//******************************************************************************
    		//第一种基本操作
    		//1.构造
    		vector()
    			: _start(nullptr)
    			, _finish(nullptr)
    			, _endOfStorage(nullptr)
    		{}
    		//1.2
    		vector(size_t n, const T& data = T())
    		{
    			_start = new T[n];
    			for (size_t i = 0; i < n; i++)
    			{
    				_start[i] = data;
    			}
    			_finish = _start + n;
    			_endOfStorage = _finish;
    		}
    		//1.3
    		vector(T*first, T*last)
    		{
    			size_t size = last - first;
    			_start = new T[size];
    			_finish = _start;
    			T* First = first;
    			while (First != last)
    			{
    				*_finish = *First;
    				First++;
    				_finish++;
    			}
    			_endOfStorage = _finish;
    		}
    		//拷贝构造函数
    		//注意浅拷贝的问题
    		vector(vector<T>& v)
    		{
    			size_t VSize = v.size();
    			_start = new T[VSize];
    			_finish = _start;
    			for (size_t i = 0; i < VSize; i++)
    			{
    				*_finish++ = v[i];
    			}
    			_endOfStorage = _finish;
    		}
    
    		//赋值运算符的重载
    		vector<T>& operator=(const vector<T>& v)
    		{
    			if (this != &v)
    			{
    				size_t VSize = v.size();
    				_start = new T[VSize];
    				_finish = _start;
    				for (int i = 0; i < VSize; i++)
    				{
    					*_finish++ = v[i];
    				}
    				_endOfStorage = _finish;
    			}
    		}
    
    		//析构
    		~vector()
    		{
    			if (_start)
    			{
    				delete[] _start;
    				_start = nullptr;
    				_finish = nullptr;
    				_endOfStorage = nullptr;
    			}
    		}
    		//******************************************************************************
    		//迭代器
    		//1.返回首位置begin
    		iterator begin()
    		{
    			return _start;
    		}
    
    		//2.返回末尾位置end
    		iterator end()
    		{
    			return _finish;
    		}
    
    		//3.反向迭代器
    		//首位置rbegin
    		reverse_iterator rbegin()
    		{
    			return end();
    		}
    
    		//4.末尾位置rend
    		reverse_iterator rend()
    		{
    			return begin();
    		}
    		//******************************************************************************
    		//容量相关操作
    		//1.获取容量有效元素的个数
    		size_t size()const
    		{
    			return _finish - _start;
    		}
    
    		//2.获取容量的大小
    		size_t capacity()const
    		{
    			return _endOfStorage - _start;
    		}
    
    		//3.判断有没有元素
    		bool empty()
    		{
    			return _finish == _start;
    		}
    
    		//4.扩容
    		void reserve(size_t NewCapacity)
    		{
    			size_t OldCapacity = capacity();
    			if (NewCapacity > OldCapacity)
    			{
    				T* temp = new T[NewCapacity];
    				size_t OldSize = size();
    				if (_start)
    				{
    					//T:是否为内置类型? typeid(T).name()
    					//编译期间确定
    					//深拷贝
    					//优点:一定不会出粗
    					//缺点:效率低
    					for (size_t i = 0; i < OldSize; i++)
    					{
    						temp[i] = _start[i];
    					}
    					//浅拷贝
    					//memcpy优点:效率高 缺陷:浅拷贝,遇到自定义对象可能会出错
    					//memcpy(temp, _start, size()*sizeof(T));
    					delete[] _start;
    				}
    				_start = temp;
    				_finish = _start + OldSize;
    				_endOfStorage = _start + NewCapacity;
    			}
    		}
    
    		//5.设置有效元素个数
    		void resize(size_t NewSize, const T& data = T())
    		{
    			size_t OldSize = size();
    			size_t _Capacity = capacity();
    			if (NewSize > OldSize)
    			{
    				if (NewSize > _Capacity)
    				{
    					reserve(NewSize);
    				}
    				
    				for (size_t i = OldSize; i < NewSize; i++)
    				{
    					*(_finish++) = data;
    				}
    
    			}
    			else if (NewSize < OldSize)
    			{
    				_finish = _start + NewSize;
    			}
    		}
    		//*******************************************************************************
    		//元素访问操作
    		//const
    		//1.随机访问
    		T operator[](size_t index)
    		{
    			size_t OldSize = size();
    			if (index >= OldSize)
    			{
    				return NULL;
    			}
    			//assert(index < OldeSize);
    			return _start[index];
    		}
    
    		const T* operator[](size_t index)const
    		{
    			size_t OldSize = size();
    			if (index >= OldSize)
    			{
    				return nullptr;
    			}
    			//assert(index < OldeSize);
    			return _start[index];
    		}
    
    		//2.访问头部元素
    		T& front()
    		{
    			return _start[0];
    		}
    
    		const T& front()const
    		{
    			return _start[0];
    		}
    		//3.访问尾部元素
    		T& back()
    		{
    			return *(_finish - 1);
    		}
    		const T& back()const
    		{
    			return *(_finish - 1);
    		}
    		//********************************************************************************
    		//元素修改操作
    		//1.尾部插入元素
    		void push_back(const T& data)
    		{
    			if (_finish == _endOfStorage)
    			{
    				size_t OldCapacity = capacity();
    				reserve(2 * (OldCapacity + 1));
    			}
    			*(_finish++) = data;
    		}
    
    		//2.尾部删除元素
    		void pop_back()
    		{
    			if (_finish == _start)
    			{
    				return;
    			}
    			_finish--;
    		}
    
    		//iterator
    		//3.任意位置插入
    		iterator insert(iterator position, const T& data)
    		{
    			if (_finish == _endOfStorage)
    			{
    				size_t OldCapacity = capacity();
    				reserve(2 * (OldCapacity + 1));
    			}
    			size_t OldSize = size();
    			if (position <= OldSize)
    			{
    				for (size_t i = OldSize; i > position; i--)
    				{
    					_start[i] = _start[i - 1];
    				}
    				_start[position] = data;
    				_finish++;
    			}
    		}
    
    		//iterator
    		//4.任意位置删除
    		iterator erase(iterator position)
    		{
    			size_t OldSize = size();
    			if (position >= OldSize)
    			{
    				return;
    			}
    			for (size_t i = position; i < OldSize; i--)
    			{
    				_start[i] = _start[i + 1];
    			}
    			_finish--;
    		}
    
    	private:
    		T* _start;
    		T* _finish;
    		T* _endOfStorage;
    	};
    }
    
    //memset设置一个字节//
    
    //打印vector
    template<class T>
    void PrintVector(FirstVector::vector<T>& v)
    {
    	for (auto& e : v)
    	{
    		cout << e << " ";
    	}
    	cout << endl;
    }
    
    //测试三种构造函数以及容量相关操作
    void TestVector()
    {
    	FirstVector::vector<int> v1;
    	FirstVector::vector<int> v2(10, 5);
    	int array[] = { 1,2,3,4,5,6,7,8,9,0 };
    	FirstVector::vector<int> v3(array, array + sizeof(array) / sizeof(array[0]));
    
    	cout << v1.empty() << endl;
    	cout << v1.size() << endl;
    	cout << v1.capacity() << endl;
    	PrintVector(v1);
    	v1.resize(6);
    	v1.reserve(10);
    	cout << v1.size() << endl;
    	cout << v1.capacity() << endl;
    
    	cout << v2.empty() << endl;
    	cout << v2.size() << endl;
    	cout << v2.capacity() << endl;
    	PrintVector(v2);
    	v2.resize(6);
    	v2.reserve(12);
    	cout << v2.size() << endl;
    	cout << v2.capacity() << endl;
    
    
    	PrintVector(v3);
    	
    }
    
    //测试拷贝构造以及复制运算符重载
    void TestVector1()
    {
    	FirstVector::vector<int> v1(10, 5);
    	FirstVector::vector<int> v2(v1);
    	FirstVector::vector<int> v3 = v1;
    	cout << v1.size() << endl;
    	cout << v1.capacity() << endl;
    	cout << v2.size() << endl;
    	cout << v2.capacity() << endl;
    	cout << v3.size() << endl;
    	cout << v3.capacity() << endl;
    	PrintVector(v1);
    	PrintVector(v2);
    	PrintVector(v3);
    }
    
    //测试元素访问系列操作
    void TestVector2()
    {
    	int array[] = { 1,2,3,4,5,6,7,8,9,0 };
    	FirstVector::vector<int> v4(array, array + sizeof(array) / sizeof(array[0]));
    	cout << v4[5] << endl;
    	cout << v4.front() << endl;
    	cout << v4.back() << endl;
    	PrintVector(v4);
    }
    
    //测试元素修改系列操作
    void TestVector3()
    {
    	FirstVector::vector<int> v5(15, 6);
    	cout << v5.size() << endl;
    	v5.push_back(8);
    	cout << v5.back() << endl;
    	cout << v5.size() << endl;
    
    	v5.pop_back();
    	cout << v5.back() << endl;
    	cout << v5.size() << endl;
    	PrintVector(v5);
    
    	//FirstVector::vector<int>::iterator v6(10, 8);
    }
    
    
    //************************************************************************************************
    //迭代器失效:迭代器本质:指针--->指针失效--->指针指向了非法的空间
    //迭代器指向的空间改变,而迭代器依旧指向原来的空间
    //1.容量发生改变(赋值,插入,resize,reserve等等)
    //2.当前迭代器所指向的元素删除(erase)
    void TestVector5()
    {
    	vector<int> v{ 1,2,3,4,5 };
    	for (auto& e : v)
    	{
    		cout << e << " ";
    	}
    	cout << endl;
    	vector<int>::iterator it = v.begin();
    	v.reserve(16);
    	it = v.begin();
    	cout << "*it = " << *it << endl;
    }
    
    void TestVector6()
    {
    	vector<int> v{ 1,2,3,4,5 };
    	for (auto& e : v)
    	{
    		cout << e << " ";
    	}
    	cout << endl;
    	vector<int>::iterator it = v.begin();
    	while (it != v.end())
    	{
    		//v.erase(it);	
    		it = v.erase(it);
    		for (auto& e : v)
    		{
    			cout << e << " ";
    		}
    		cout << endl;
    	}
    }
    //it = v.erase(it);
    //for (auto& e : v)
    //{
    //	cout << e << " ";
    //}
    //cout << endl;
    int main()
    {
    	TestVector6();
    	system("pause");
    	return 0;
    }
    //********************************************************************************************
    

    浅拷贝:优点:效率高。但是存在问题就是遇到自定义对象可能会出错。

    深拷贝:优点:一定不会出错。但是效率低。

    所以在是否用深拷贝还是浅拷贝时,根据具体情况而定,二者综合使用也是可以。

    ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?珍&源码

    cs
    下一篇:没有了