C++vector模拟实现增删改查

一.成员变量

vector的成员变量有三个,分别是三个类模板参数类型的指针_start,_finish,_endofstorage,它们分别指向vector数组的首个元素,结尾元素的下一个空间,空间末尾。

二.构造函数(默认构造,拷贝构造函数,赋值重载函数,迭代器实现构造函数) 

		
        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;
			}
			_endofstorage = _finish;
		}
        //拷贝构造函数
		vector(const vector& v)
		{
			//创建新对象,然后交换对象内的值,就可以完成深拷贝操作,这是深拷贝的现代写法
			vector tmp(v.begin(), v.end());
			Swap(tmp);
		}

		//赋值重载函数
		vector& operator=(vector v)
		{
			swap(v);
			return *this;
		}

二.reserve函数

2.1功能

改变当前vector对象空间容量的大小,如果需要改变的容量大小大于vector对象的实际容量,就重新申请空间,扩容,否则就不需要扩容。

2.2返回值

无返回值

2.3实现逻辑

(1)判断需要扩容的容量n是否大于当前对象的实际容量

(2)记录vector上的元素个数,并且在堆上申请大小n为的空间

(3)如果_start指针为空,这直接将_start指针指向堆上申请的空间

(4)将对象中的数据拷贝到在堆上新开辟的空间上,并释放该数据指向的堆上的空间

(5)改变当前对象的实际容量值

//改变vector的容量大小
		void reserve(size_t n)
		{
			if (n > capacity())
			{
				size_t num = size();
				T* tmp = new T[n];
				if (_start == nullptr)
				{
					_start = tmp;
					_finish = _start + num;
					_endofstorage = _start + n;
				}
				else
				{

					//memcpy(tmp, _start, sizeof(T) * size());对于自定义类型,这种写法会发生浅拷贝,导致析构的时候,发生了两次析构
					//这种写法能有效避免自定义类型的浅拷贝问题
					for (size_t i = 0; i < num; i++)
					{
						tmp[i] = _start[i];//对于自定义类型,这里会发生深拷贝
					}
					delete[] _start;
					_start = tmp;
					_finish = _start + num;
					_endofstorage = _start + n;

				}
			}
		}

实现结果:

C++vector模拟实现增删改查_第1张图片 

三.resize函数

3.1功能

改变当前vector对象的元素的实际个数以及改变容量大小,并且初始化

3.2返回值

无返回值

3.3实现逻辑

(1)判断需要改变的容量n是否大于当前对象的实际个数

(2)如果n小于等于当前对象的实际个数,就将该对象的_finish指针指向vector空间中的第n个元素。

(3)如果n大于等于当前对象的实际个数并且大于当前对象的实际容量,就调用reserve函数扩容vector对象的实际容量到n

(4)将_finish指针指向的空间赋值为val,再将_finish向后移

		//改变容量,还有初始化
		void resize(size_t n, T& val = T())
		{
			if (n < size())
			{
				_finish = _start + n;
			}
			else
			{
				if (n > capacity())
				{
					reserve(n);

				}
				while (_finish != _start + n)
				{
					*(_finish) = val;
					++_finish;
				}
			}
		}

实现结果: 

 C++vector模拟实现增删改查_第2张图片

 四.insert函数

4.1功能

在vector数组中的任意位置插入单个元素

 4.2返回值

返回插入位置的迭代器

4.3实现逻辑

(1)判断_finish指针是否等于_endofstorage指针,即判断是否需要扩容

(2)如果需要扩容,先记录下插入位置的迭代器(指针)pos在vector数组中的相对位置,然后调用reserve函数扩容,扩容会产生新的vector数组,但是该数组中的数据没有改变,只是指向该数组的指针发生了变化,所以需要在新的vector数组中更新迭代器(指针)pos。

(3)声明一个迭代器(指针)end,它指向该vector对象的最后一个元素,然后从end开始到pos,将一个一个元素向后移一位

(4)迭代器(指针)pos指向的空间赋值为x,再将_finish向后移

(5)返回迭代器(指针)pos

		iterator insert(iterator pos, const T& x)
		{
			assert(pos >= _start);
			assert(pos <= _finish);
			if (_finish == _endofstorage)
			{
				//扩容可能会导致pos失效,所以需要在扩容之前记录pos的位置,扩容后更新一下pos
				int len = pos - _start;
				reverve(capacity() == 0 ? 4 : 2 * capacity());
				iterator pos = _start + len;
			}
			iterator end = _finish - 1;
			while (end >= pos)
			{
				*(end + 1) = *(end);
			}
			*(pos) = x;
			_finish++;

			return pos;
		}

实现结果:

C++vector模拟实现增删改查_第3张图片五.erase函数

5.1功能

从vector数组中迭代器(指针)pos位置的值

5.2返回值

返回删除后,删除位置的元素的指针

5.3实现逻辑

(1)声明一个迭代器it,它等于pos

(2)将it到_finish之间的元素全部向前移一位

(3)将_finish向前移一位,返回迭代器pos

		//删除vector中的某一个元素
		iterator erase(iterator pos)
		{
			assert(pos >= _start);
			assert(pos < _finish);
			iterator it = pos;
			while (it < _finish - 1)
			{
				*(it) = *(it + 1);
				++it;
			}
			_finish--;
			//iterator begin = pos + 1;
			//while (begin < _finish)
			//{
			//	*(begin - 1) = *begin;
			//	++begin;
			//}
			//--_finish;

			return pos;
		}

 实现结果:

C++vector模拟实现增删改查_第4张图片

 六.find函数

6.1功能

从vector数组中找到对应的元素

6.2返回值

如果找到了就返回对应元素位置的迭代器,如果没找到就返回最后一个元素的下一个位置的迭代器。

6.3实现逻辑

(1)通过传过来的首元素的迭代器,和末尾元素的迭代器,遍历整个vector数组,

(2)解引用每个迭代器,然后和val作比较,如果相等,就会返回该迭代器

(3)如果没有一个匹配的迭代器,就返回最后一个元素的下一个位置的迭代器

	//查找函数
	template 
	InputIterator find(InputIterator first, InputIterator last, const T& val)
	{
		assert(first <= last);
		while (first != last)
		{
			if (*first == val)
			{
				return first;
			}
			++first;
		}
		return last;
	}

 

 

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