[C++]:11.模拟实现vector

发布时间:2024年01月16日

二.模拟实现vector

0.看一看源码SGI

1.vector.h

在这里插入图片描述

vector.h中其实包含了许多的头文件,我们在cpp中包含文件的时候头文件中还会去展开这四个头文件关于vector类主要在这个stl_vector.h中。

2.stl_vector.h

1.构造:

在这里插入图片描述

ps:在当前的学习阶段看源码不要一行一行去看因为水平不足所以非常多基本上是看不懂的所以不要去一行一行去看要全方面的去看有一些看不懂问题不大。

在这里插入图片描述

在这里插入图片描述

2.析构函数:

在这里插入图片描述

3.push_back()

在这里插入图片描述

1.构造函数:

1-1:参数为空的!

1.构造函数的初始化列表给全空:
2.构造函数的内容给赋值全空:
3.C++11 支持的声明变量的时候初始化(走的初始化列表):
4.综上所述第三个方法最方便:我们都可以在定义的时候去初始化非常的方便。


vector(size_t n , const T& val=T())
	:start(nullptr)
	,finish(nullptr)
	,end_of_storage(nullptr)
{
}

vector()
{
		start = nullptr;
		finish = nullptr;
		end_of_storage = nullptr;
}


private:
	iterator start = nullptr;
	iterator finish = nullptr;
	iterator end_of_storage = nullptr;


1-2:n个数据的!

情况一:n个数据传第二个参数初始化数据的:
情况二:n个数据不传第二个参数就开空间不初始化的:
1.对于我情况二的操作其实本质是初始化容量空间为全 val (内置类型的默认构造值),但是我的finish == start所以在后面使用的时候数据进入是赋值进入:

vector(size_t n , const T& val=T())
			{
				resize(n,val);
			}
vector(int n , const T& val=T())
			{
				resize(n,val);
			}

1-3:范围构造:

//1-3:范围初始化:
//1-4:使用新的模板方便使用不同类型的迭代器进行范围构造
			template<class InputIterator>
			vector(InputIterator left, InputIterator right)
			{
				while (left != right)
				{
					push_back(*left);
					left++;
				}
			}

2.析构函数:

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

3.迭代器+遍历数据:

3-1:迭代器:

在这里插入图片描述

在这里插入图片描述

//3.迭代器:
		
			iterator begin()const
			{
				return start;
			}
			iterator end()const
			{
				return finish;
			}

			iterator_const cbegin()const
			{
				return start;
			}
			iterator_const cend()const
			{
				return finish;
			}

			iterator rbegin()const
			{
				return finis - 1;
			}
			iterator rend()const
			{
				return start-1;
			}

			iterator_const crbegin()const
			{
				return finis - 1;
			}
			iterator_const crend()const
			{
				return start - 1;
			}

3-2:数据遍历:

void print_value()const
			{
				assert(start != end_of_storage);
				int num = finish - start;

				for (int i = 0; i < num; i++)
				{
					cout << *(start + i) << " ";
				}
				cout << endl;
			}

			T& operator[](size_t pos)
			{
				return *(start + pos);
			}
void text_2()
{
	sfpy::vector<int> v1(10, 2);
	sfpy::vector<int> v2(v1);
	sfpy::vector<int> v3(10);

	sfpy::vector<int>::iterator it_1 = v1.begin();
	while (it_1 != v1.end())
	{
		cout << *it_1 << " ";
		it_1++;
	}
	cout << endl;

	v1.print_value();

	for (int i = 0; i < v1.size(); i++)
	{
		cout << v1[i] << " ";
	}
	cout << endl;


	sfpy::vector<int>::iterator it_2 = v2.begin();
	while (it_2 != v2.end())
	{
		cout << *it_2 << " ";
		it_2++;
	}

	cout << endl;

	v2.print_value();

	for (int i = 0; i < v2.size(); i++)
	{
		cout << v2[i] << " ";
	}
	cout << endl;
}

4.空间问题:

在这里插入图片描述

4-1:size() 和capacity

//4.size() 和 capacity()

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

4-2:resize 和 reserve:

void reserve(size_t n)
			{
				//assert(n > capacity());
				//1.重新配置空间:
				T* tmp = new T[n];

				if (n > capacity())
				{
					size_t n_1 = size();
					for (size_t i = 0; i < n; i++)
					{
						if (i < n_1)
						{
							tmp[i] = *(start + i);
						}
						else
						{
							tmp[i] = T();
						}
					}
					delete[] start;
					start = tmp;
					finish = tmp + n_1;
					end_of_storage = tmp + n;
				}
			}

			void resize(size_t n, T val = T())
			{
				if (n > size())
				{
					reserve(n);
					while (finish < start + n)
					{
						*finish = val;
						++finish;
					}
				}
				else
				{
					finish = start + n;
				}
			}

1.关于reserve的补充:
2.为什么不去使用memcpy这样的的函数本质这是一个浅拷贝。
3.调用delete[] 释放空间+调用析构函数。
4.内置类型使用memcpy没有问题。
5.对于自定义类型来说使用memcpy会产生浅拷贝的问题

在这里插入图片描述

在这里插入图片描述

4-3:empty

bool empty()
{
		if (size() == 0)
		{
			return true;
		}
		else
		{
			return false;
		}
}

4-4:shrink_to_fit

void shrink_to_fit()
{
	assert(size() >= capacity);

	//1.重新配置空间:
	size_t n = size();
	T* tmp = new T[n];

	//减少:
	memcpy(tmp, start, size(T) * n);

	start = tmp;
	finish = end_of_storage = tmp + n;
}

5.增删查改:

5-1:push_back()

void push_back(const T& val)
{
	if (finish == end_of_storage)
	{
		size_t new_capacity =(start == finish ? 4 : (capacity() * 2));			
		reserve(new_capacity);
	}

	(*finish) = val;
	finish++;
}

在这里插入图片描述

5-2:pop_back()

void pop_back()
{
	assert(size() != 0);
	//resize(size() - 1);
	(*finish) = T();
	finish--;
}

在这里插入图片描述

5-3:find()

在这里插入图片描述

1.find()是一个全局函数不是一个特定的类就有一个find() .
2.find()是通过类模板实现的。
3.find()的返回值是一个iterator。

template <class T>
	T* find(T* first, T* last, const T& val)
	{
		while (first != last)
		{
			if (*first == val) 
				return first;

			++first;
		}
		return last;
	}

在这里插入图片描述

5-4:insert() :在find之前插入

在这里插入图片描述

iterator insert(iterator position, const T& val)
{
				size_t pos = position - start;
				size_t n = size();

				if (finish == end_of_storage)
				{
					size_t new_capacity = (start == finish ? 4 : (capacity() * 2));
					reserve(new_capacity);
				}

				//void * memmove ( void * destination, const void * source, size_t num );

				memcpy(start + pos + 1, start + pos, (n - (pos))*sizeof(T));
				*(start + pos) = val;
				finish++;

				return start + pos;
}

在这里插入图片描述

5-5:erase() : 删除find位置

在这里插入图片描述

iterator erase(iterator position)
			{
				assert(size() != 0);

				size_t pos = position - start;
				size_t n = size();

				//void * memmove ( void * destination, const void * source, size_t num );
				memcpy(start + pos , start + pos +1, (n - (pos+1)) * sizeof(T));
				finish--;

				return start + pos;
			}

在这里插入图片描述

5-6:insert和erase

1.在vs下insert和erase传进去的迭代器在使用之后就不可以继续使用了(有可能发生迭代器失效的情况)。
2.在vs下是会认为迭代器失效。
3.模拟实现insert和erase —> insert返回插入新的元素的迭代器,erase返回删除元素的下一个元素的迭代器。
4.pos就不要继续使用应该去使用insert和erase的返回值。

文章来源:https://blog.csdn.net/2201_75943325/article/details/134910187
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。