【c++vector】vector的实现和深层次的深浅拷贝

目录

 

1.深层次的深浅拷贝

2.vector的实现

                2.迭代器和打印函数

                3.reserve和resize

                4.拷贝构造函数和赋值运算符重载

                5.插入和删除 

                全部代码


1.深层次的深浅拷贝

步骤:

  1. 自己的实现容量初始为4个,增容2倍,当尾插的4个数,再插入第5个数时会发生增容;
  2. 使用memcpy增容或者拷贝构造,都会是深层次的浅拷贝

总结:

  1. T是内置类型(int)或者是浅拷贝自定义类型(date),他们增容和拷贝构造中,使用memcpy是没有问题的;
  2. 但是T是深拷贝自定义类型(string),他们增容和拷贝构造中,使用memcpy浅拷贝,指向1块相同的空间,是有问题的;
  3. STL库里面是类型萃取区分类型(了解):memcpy效率更高(内置类型,浅拷贝自定义类型),遍历+深拷贝自定义类型(string)的赋值运算符重载会,开空间+拷贝构造效率更低(深拷贝自定义类型)

解决:把memcpy替换为遍历+深拷贝自定义类型(string)的赋值运算符重载;

for (size_t i = 0; i < v.size(); i++)//解决深层次的深浅拷贝
			{
				
				_start[i] = v._start[i];
			}

逻辑如图:

【c++vector】vector的实现和深层次的深浅拷贝_第1张图片

代码: 

#include
#include
#include
#include
using namespace std;

namespace lj
{
	template
	class vector
	{
	public:
		typedef T* iterator;
		typedef const T* const_iterator;

		vector(const vector& v)//拷贝构造
			:_start(nullptr)
			,_finish(nullptr)
			,_endofstorage(nullptr)
		{
			_start = new T[v.capacity()];
		    memcpy(_start, v._start, sizeof(T) * v.capacity());
			//for (size_t i = 0; i < v.size(); i++)//解决深层次的深浅拷贝
		    //{
			//	_start[i] = v._start[i];
			//}
			_endofstorage = _start + v.capacity();
			_finish = _start + v.size();
		}

		void reserve(size_t n)
		{
			if (n > capacity())
			{
				size_t sz = size();
				iterator tmp = new T[n];
				if (_start)//start不为为空
				{
					memcpy(tmp, _start, sz*sizeof(T));
					//for (size_t i = 0; i << sz; i++)
					//{
						//tmp[i] = _start[i];
					//}
					delete[] _start;
				}
				_start = tmp;
				_finish = _start+sz;
				_endofstorage=_start+n;
			}
		}
		void push_back(const T& x)
		{
			if (_finish == _endofstorage)
			{
				size_t newCapacity = capacity() == 0 ? 4 : capacity() * 2;
				reserve(newCapacity);
			}
			*_finish = x;
			_finish++;
		}
	private:
		iterator _start;
		iterator _finish;
		iterator _endofstorage;
	};
	void test_vector6()
	{
		vector v;
		v.push_back("1111");
		v.push_back("2222");
		v.push_back("3333");
		v.push_back("4444");
		v.push_back("5555");
		vector v1(v);
		v.PrintVector();
		v1.PrintVector();
	}
}
int main()
{

	lj::test_vector6();
	return 0;
}

2.vector的实现

                1.构造函数和析构函数

  • 使用迭代器构造函数时,可以是任意类型(int,sting,double)所以把迭代器构造函数写成一个模板函数;类模板的成员函数,还可以再是函数模板
		vector()
			:_start(nullptr)
			,_finish(nullptr)
			,_endofstorage(nullptr)
		{}
        // 类模板的成员函数,还可以再是函数模板
		template
		vector(InputIterator first, InputIterator last)
			: _start(nullptr)
			, _finish(nullptr)
			, _endofstorage(nullptr)
		{
			while (first != last)
			{
				push_back(*first);
				++first;
			}
		}
		~vector()
		{
			if (_start)
			{
				delete[] _start;
				_start = _finish = _endofstorage = nullptr;
			}
		}

                2.迭代器和打印函数

  • 一个接口需要可读和可读可写的时候,那么写成两份
const_iterator begin()const
		{
			return _start;
		}
const_iterator end()const
		{
			return _finish;
		}
	iterator begin()
		{
			return _start;
		}
	iterator end()
		{
			return _finish;
		}
void PrintVector()const
		{
			vector::const_iterator it = this->begin();
			while (it != this->end())
			{
				//*it += 1;//只能读,不能写
				cout << *it << " ";
				++it;
			}
			cout << endl;
		}

                3.reserve和resize

  • reserve最后_finish = _start+sz;和_endofstorage=_start+n;不能写成_start+size()和_start+capacity(),因为计算是_finish和_endofstorage还是nullptr,求size()和capacity()会是一个很大的负值
  • resize3中情况:减少size;增加size,但是不用增容;增加size也需要增容
void reserve(size_t n)
		{
			if (n > capacity())
			{
				size_t sz = size();
				iterator tmp = new T[n];
				if (_start)//start不为为空
				{
					//memcpy(tmp, _start, sz*sizeof(T));
					for (size_t i = 0; i << sz; i++)
					{
						tmp[i] = _start[i];
					}
					delete[] _start;
				}
				_start = tmp;
				_finish = _start+sz;//finish还为0,start新空间,size()会返回很大的负值
				_endofstorage=_start+n;//endofstorage还为0,start新空间,capacity()会返回很大的负值
			}
		}
		void resize(size_t n, T val = T())
		{
			if (n < size())
			{
				_finish = _start + n;
			}
			else
			{
				if (n > capacity())
				{
					reserve(n);

				}
				for (size_t i = size(); i < n; i++)
				{
					*_finish = val;
					_finish++;
				}
			}
		}

                4.拷贝构造函数和赋值运算符重载

  • 拷贝构造注意深层次的深浅拷贝;
  • 赋值运算符重载现代写法思想:传值传参,交换之后,因为v是临时对象,出函数生命周期结束,那么会释放交换后的数组;   
vector(const vector& v)//拷贝构造
			:_start(nullptr)
			,_finish(nullptr)
			,_endofstorage(nullptr)
		{
			_start = new T[v.capacity()];
			/*memcpy(_start, v._start, sizeof(T) * v.capacity());*/
			for (size_t i = 0; i < v.size(); i++)//解决深层次的深浅拷贝
			{
				
				_start[i] = v._start[i];
			}
			_endofstorage = _start + v.capacity();
			_finish = _start + v.size();
		}
		vector& operator=(vector v)
		{
			swap(_start, v._start);
			swap(_finish, v._finish);
			swap(_endofstorage, v._endofstorage);
			return *this;
		}

                5.插入和删除 

  • insert增容后注意更新一下pos,防止迭代器失效;
		void push_back(const T& x)
		{
			if (_finish == _endofstorage)
			{
				size_t newCapacity = capacity() == 0 ? 4 : capacity() * 2;
				reserve(newCapacity);
			}
			*_finish = x;
			_finish++;
		}
		void pop_back()
		{
			assert(!empty());
			--_finish;
		}
		void insert(iterator pos, const T& x)
		{
			size_t sz = pos - _start;
			if (_finish == _endofstorage)//判断增容
			{
				size_t newCapacity = capacity() == 0 ? 4 : capacity() * 2;
				reserve(newCapacity);
				//更新pos,防止迭代器失效
				pos = _start + sz;
			}
			iterator end = _finish - 1;
			while (end >= pos)
			{
				*(end + 1) = *end;
				--end;
			}
			*end = x;
			++_finish;
		}
		iterator erase(iterator pos)
		{
			iterator it = pos + 1;
			while (it != end())
			{
				*(it - 1) = *it;
				++it;
			}
			_finish--; 
			return pos;
		}

                全部代码

#include
#include
#include
#include
using namespace std;

namespace lj
{
	template
	class vector
	{
	public:
		typedef T* iterator;
		typedef const T* const_iterator;
		const_iterator begin()const
		{
			return _start;
		}
		const_iterator end()const
		{
			return _finish;
		}
		iterator begin()
		{
			return _start;
		}
		iterator end()
		{
			return _finish;
		}
		vector()
			:_start(nullptr)
			,_finish(nullptr)
			,_endofstorage(nullptr)
		{}
		// 类模板的成员函数,还可以再是函数模板
		template
		vector(InputIterator first, InputIterator last)
			: _start(nullptr)
			, _finish(nullptr)
			, _endofstorage(nullptr)
		{
			while (first != last)
			{
				push_back(*first);
				++first;
			}
		}
		~vector()
		{
			if (_start)
			{
				delete[] _start;
				_start = _finish = _endofstorage = nullptr;
			}
		}
		vector(const vector& v)//拷贝构造
			:_start(nullptr)
			,_finish(nullptr)
			,_endofstorage(nullptr)
		{
			_start = new T[v.capacity()];
			/*memcpy(_start, v._start, sizeof(T) * v.capacity());*/
			for (size_t i = 0; i < v.size(); i++)//解决深层次的深浅拷贝
			{
				
				_start[i] = v._start[i];
			}
			_endofstorage = _start + v.capacity();
			_finish = _start + v.size();
		}
		vector& operator=(vector v)
		{
			swap(_start, v._start);
			swap(_finish, v._finish);
			swap(_endofstorage, v._endofstorage);
			return *this;
		}
		/*vector& operator=(const vector& v)
		{
			if(_start!=v._start)
			{
				delete[] _start;
				_start = new T[v.capacity()];
				memcpy(_start, v._start, sizeof(T) * v.capacity());
				_endofstorage = _start + v.capacity();
				_finish = _start + v.size();
			}
			return *this;
		}*/
		size_t size()const
		{
			return _finish - _start;
		}
		size_t capacity()const
		{
			return _endofstorage - _start;
		}
		void reserve(size_t n)
		{
			if (n > capacity())
			{
				size_t sz = size();
				iterator tmp = new T[n];
				if (_start)//start不为为空
				{
					//memcpy(tmp, _start, sz*sizeof(T));
					for (size_t i = 0; i << sz; i++)
					{
						tmp[i] = _start[i];
					}
					delete[] _start;
				}
				_start = tmp;
				_finish = _start+sz;//finish还为0,start新空间,size()会返回很大的负值
				_endofstorage=_start+n;//endofstorage还为0,start新空间,capacity()会返回很大的负值
			}
		}
		void resize(size_t n, T val = T())
		{
			if (n < size())
			{
				_finish = _start + n;
			}
			else
			{
				if (n > capacity())
				{
					reserve(n);

				}
				for (size_t i = size(); i < n; i++)
				{
					*_finish = val;
					_finish++;
				}
			}
		}
		bool empty()
		{
			return _start == _finish;
		}
		void push_back(const T& x)
		{
			if (_finish == _endofstorage)
			{
				size_t newCapacity = capacity() == 0 ? 4 : capacity() * 2;
				reserve(newCapacity);
			}
			*_finish = x;
			_finish++;
		}
		void pop_back()
		{
			assert(!empty());
			--_finish;
		}
		void insert(iterator pos, const T& x)
		{
			size_t sz = pos - _start;
			if (_finish == _endofstorage)//判断增容
			{
				size_t newCapacity = capacity() == 0 ? 4 : capacity() * 2;
				reserve(newCapacity);
				//更新pos,防止迭代器失效
				pos = _start + sz;
			}
			iterator end = _finish - 1;
			while (end >= pos)
			{
				*(end + 1) = *end;
				--end;
			}
			*end = x;
			++_finish;
		}
		iterator erase(iterator pos)
		{
			iterator it = pos + 1;
			while (it != end())
			{
				*(it - 1) = *it;
				++it;
			}
			_finish--; 
			return pos;
		}
		void PrintVector()const
		{
			vector::const_iterator it = this->begin();
			while (it != this->end())
			{
				//*it += 1;//只能读,不能写
				cout << *it << " ";
				++it;
			}
			cout << endl;
		}
	private:
		iterator _start;
		iterator _finish;
		iterator _endofstorage;
	};
	void test_vector1()
	{
		vector v;
		v.push_back(1);
		v.push_back(2);
		v.push_back(3);
		v.push_back(4);
		v.push_back(5);
		v.push_back(6);
		vector::iterator it = v.begin();
		while (it != v.end())
		{
			cout << *it << " ";
			++it;
		}
		cout << endl;
		v.PrintVector();
	}
	void test_vector2()
	{
		vector v;
		v.push_back(1);
		v.push_back(2);
		v.push_back(3);
		v.push_back(4);
		v.push_back(5);
		v.push_back(6);
		//v.pop_back();
		v.resize(3);
		v.resize(6,1);
		v.resize(12,2);
		vector::iterator it = v.begin();
		while (it != v.end())
		{
			cout << *it << " ";
			++it;
		}
		cout << endl;
	}
	void test_vector3()
	{
		vector v;
		v.push_back(1);
		v.push_back(2);
		v.push_back(3);
		v.push_back(4);
		v.push_back(5);
		v.push_back(6);
		vector::iterator pos = find(v.begin(), v.end(), 3);
		v.insert(pos, 30);
		v.PrintVector();
	}
	void test_vector4()
	{
		vector v;
		v.push_back(1);
		v.push_back(2);
		v.push_back(3);
		v.push_back(4);
		v.push_back(5);
		v.push_back(6);
		vector::iterator pos = find(v.begin(), v.end(), 3);
		v.erase(pos);
		v.PrintVector();
	}
	void test_vector5()
	{
		vector v;
		v.push_back(1);
		v.push_back(2);
		v.push_back(3);
		vector v1(v);
		vector v2;
		v1=v2=v;

		v.PrintVector();
		v1.PrintVector();
		v2.PrintVector();
	}
	void test_vector6()
	{
		vector v;
		v.push_back("111111111111111111");
		v.push_back("2222");
		v.push_back("3333");
		v.push_back("4444");
		v.push_back("5555");
		vector v1(v);


		v.PrintVector();
		v1.PrintVector();
	}
}
int main()
{
	//lj::test_vector1();
	//lj::test_vector2();
	//lj::test_vector3();
	lj::test_vector6();
	return 0;
}

你可能感兴趣的:(c++,c++,开发语言)