重生之C++学习:vector

目录

vector的使用

vector的迭代

vector需要注意的点

resize和reserve

find方法

vector实现二维数组

vector的实现

vector的框架

vector的长度与容量

vector的构造与析构函数

vector的增删

简易的vector

测试函数

最终代码

vector的使用

  首先vector是一个长度可以变化的顺序表,类似string是一个写好的数据结构

vector的迭代

// vector的使用
void test_vector1() {

	vector<int> v1;
	vector<int> v2(10, 0);

	v1 = v2;

	vector<int> v3(v2.begin(), v2.end());

	for (size_t i = 0; i < v1.size(); i++) {

		cout << v1[i];
	}
	cout << endl;

	vector<int>::iterator it = v2.begin();
	// auto it = v2.begin();

	while (it != v2.end()) {

		cout << *it;
		it++;
	}
	cout << endl;

}

vector需要注意的点

resize和reserve
void test_vector2() {

	// 关于vector中的resize 和 reserve

	vector<int> v;
	// v.reserve(100);	// size = 0		capacity = 100
	v.resize(100);		// size = 100	capacity = 100

	// 当为reserve(100)时仅仅开了空间,size为0,无法实现

	for (size_t i = 0; i < v.size(); i++) {

		v[i] = i;
		cout << v[i] << ' ';
	}
	cout << endl;
	cout <<"vector<int> max_size(): " << v.max_size() << endl;
}
find方法

vector - C++ Reference

我们在查阅vector文档时,发现vector没有像string那样子重载find方法,带着疑惑我们了解到vector使用了标准库中的全局find方法。在研究会我们发现,string对应的是字符串对象,而vector<类型名>随着类型的改变而改变存储的数据类型,也就是既可以存储数字,也可以存储字符串,那么就需要用模版来实现多种数据类型的find,因此就使用全局find,语法也与string有差异

void test_vector3() {

	vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(1);
	
	v.insert(v.begin(), 6);
	v.insert(v.end(), 6); 
	for (size_t i = 0; i < v.size(); i++) {

		cout << v[i] << ' ';
	}
	cout << endl;

	// 通过迭代器查找位置
	auto it = find(v.begin(), v.end(), 2);
	// 查找到插入
	if (it != v.end()) {
		v.insert(it, 3);
		// v.insert(it + 1, 3); 不知道为什么这里多加这一句会报错,两句好像只能有一句
	}

	for (size_t i = 0; i < v.size(); i++) {

		cout << v[i] << ' ';
	}
	cout << endl;

	// insert 和 erase 使用完后会导致迭代器失效,需要再次查找迭代器位置

	it = find(v.begin(), v.end(), 3);
	//	v.erase(it) 就只是删掉it这个位置
	v.erase(it,v.end());
	for (size_t i = 0; i < v.size(); i++) {

		cout << v[i] << ' ';
	}
	cout << endl;

}

这里的代码块中我们也要注意,用find通过迭代器,进行增删(insert erase)操作后迭代器会失效,这一部分的内容在后续知识体系会讲解

vector实现二维数组

二维数组是由一维数组嵌套而成的,如果一个数组的每个元素又是一个数组,那么它就是二维数组。在C语言中,一个二维数组可以分解为多个一维数组,并且这些一维数组可以直接拿来使用。每个一维数组有自己的索引,可以通过索引来访问二维数组中的元素

在讲vector实现二维数组之前,我们先讲一下c语言中实现二维数组

除了通过直接定义二维数组,我们也可以通过指针数组来实现二维数组,实际上一般我们通过指针数组来进行,因为需要调用函数

int* array;    // 对应着一维数组,放着行

int** aArray;    // 对应着二维数组,里面放着列的地址

// 通过malloc我们就可以看出

array = (int*)malloc(sizeof(int)*一维数组的长度);

aArray = (int**)malloc(sizeof(int*)*某个长度下标一维数组的个数);

接下来进行就通过双层循环来遍历赋值给二维数组,这里我们发现对于c语言的二维数组还是特别麻烦,不过我们学习了高级语言cpp那么接下来就是cpp的场子

上面我们说过vector是一个写好的数据结构,那么我们从底层来分析

如果现在还有已获得话那就借助一道杨辉三角来收尾解答

杨辉三角力扣

class Solution {
public:
    vector<vector<int>> generate(int numRows) {
        vector<vector<int>> vv;
        vv.resize(numRows);

        for(size_t i = 0; i < vv.size(); i++){

            vv[i].resize(i + 1, 0);
            vv[i][0] = vv[i][vv[i].size()-1] = 1;
        }
        for(size_t i = 0; i < vv.size(); i++){

            for(size_t j = 0; j < vv[i].size(); j++){

                if(vv[i][j] == 0){

                    vv[i][j] = vv[i-1][j-1] + vv[i-1][j];
                }
            }
        }
        return vv;
    }

};

vector的实现

与string类似,所以我们就缩减篇幅直接进行vector的实现

如图 与传统的_array,_size,_capacity不同,vector用的是三个指针(迭代器)_start,_finish, _end_of_storage,来实现功能,本质上两种实现是一致的

vector的框架

	template<class T>

	class my_vector {
		

	public:

		typedef T* iterator;	// iterator表示某个类型的指针
		typedef const T* const_iterator;


	private:
		// 数组的头,  相当于 type* _array 
		iterator _start;
		// 数组有效数据的尾巴,  相当于 _array + _size
		iterator _finish;
		// 数组空间的尾巴,  相当于_array + _capacity
		iterator _end_of_storage;
	};

vector的长度与容量

我们知道通过指针间的减法,可以获得这两个指针间的有效数据个数,所以就能获得_size,_capacity,而_start本质上就是_array

		// vector的返回参数
		size_t capacity() const {		// vector的容量

			return _end_of_storage - _start;
		}
		size_t size() const {		// 返回vector的大小

			return _finish - _start;
		}

除了长度和容量的表示,我们大多时候还要面对顺序表长度的改变,以及容量的扩大

		void reserve(size_t n) {	// 扩容函数

			if (n > capacity()) {

				size_t _size = size();
				T* tmp = new T[n];
				if (_start) {
					// 手动拷贝
					for (size_t i = 0; i < _size; i++) {

						tmp[i] = _start[i];
					}
					delete[] _start;
				}

				_start = tmp;
				_finish = _start + _size;	// 这里有个隐藏的坑,_size这个变量取消,然后换size()
				_end_of_storage = _start + n;
			}
		}	
		void resize(size_t n, const T& data = T()) {	// 大小重置

			if (n <= size())
				_finish = _start + n;
			else {
				
				reserve(n);	// 借助reserve()判断大小大于容量的话会扩容,小于容量不会扩容
				while (_finish < _start + n) {

					*_finish = data;
					_finish++;
				}
			}
				
		}

看这块代码块,有一个隐藏的坑,如果取消了_size这个临时变量

那么因为 size() 这个函数在 _finish = _start + size(); 中,_start已经改变了,而原来的_finish没有改变,并且已经不是原来同一个数组的头尾地址,导致这样子运算最终报错

vector的构造与析构函数

		my_vector()
			:_start(nullptr)
			, _finish(nullptr)
			, _end_of_storage(nullptr)
		{

		}
		my_vector(const my_vector<T>& v)
			:_start(nullptr)
			, _finish(nullptr)
			, _end_of_storage(nullptr)
		{
			reserve(v.capacity());
			for (auto& e : v) {	// 将数据插入

				push_back(e);
			}
		};
		template<class inputIterator>
		my_vector(inputIterator first, inputIterator end) {	// 通过迭代器拷贝构造某一部分

			while (first != end) {

				push_back(*first);
				first++;
			}
		}
		my_vector(int n, const T& data = T()) {		// 防止传入的为(10,0)调用模版(上一个构造函数)

			reserve(n);
			for (int i = 0; i < n; i++) {

				push_back(data);
			}
		}
		my_vector(size_t n, const T& data = T()) {

			reserve(n);
			for (size_t i = 0; i < n; i++) {

				push_back(data);
			}
		}

		~my_vector() {	// 析构

			delete[] _start;
			_start = _finish = _end_of_storage = nullptr;
		}


这里着重讲一下通过迭代器来进行拷贝构造

这个就是通过类内,定义模版来实现迭代器,不过正因为是模版,inputIterator也可以为int类型,这里听得可能有点蒙,那我给个例子

my_vector<int> v1;
my_vector<int> v2;

v2 = v1(10,0);

v2 = v1(v1.begin(), v1.end())

你说v2 = v1(10,0);会不会进入这个迭代器构造函数,答案是会的,那么对于int类型,*(int类型)就会报错,解引用操作符无法对int使用。那么如何解决呢,于是乎就多引入了两个构造函数,通过更加匹配,所以编译器会主动进行相匹配的构造函数,而不进入迭代器构造函数

vector的增删

		// 插入
		void push_back(const T& data) { // 插入单个数据

			if (_finish == _end_of_storage) {

				reserve(capacity() == 0 ? 4 : capacity() * 2);
			}

			*_finish = data;
			_finish++;

		}
		void insert(iterator postion, const T& data) {

			assert(postion >= _start && postion <= _finish);
			
			size_t pos_len = postion - _start;	// 记录相对位置,防止扩容后postion失效
			
			if (_finish == _end_of_storage) {

				reserve(capacity() == 0 ? 4 : capacity() * 2);
				postion = _start + pos_len;		// 扩容产生新的postion
			}

			// 注意扩容可能导致迭代器失效

			iterator flag = _finish - 1;	
			while (flag >= postion) {

				*(flag + 1) = *flag;
				flag--;
			}
			*postion = data;
			_finish++;

		}

		// 删除
		iterator erase(iterator postion) {
			// 注意当删除了postion时可能会导致迭代器失效,即前后地址不连续,导致无法找到
			// 连续使用的时候需要保留postion前后的迭代器地址

			assert(postion >= _start && postion < _finish);
			iterator flag = postion + 1;
			
			while (flag < _finish) {
				*(flag - 1) = *flag;
				flag++;
			}
			_finish--;
			// 这里返回了
			return postion;
		}
	

注意对于insert和erase这两个函数,通过iterator这个迭代器的过程中,会导致迭代器失效

!来自C知道的回答!

vector中的迭代器会失效的原因有以下几点:

  1. 添加元素:当向vector中添加元素时,如果当前容量不足,会重新分配一块更大的内存空间,并将原有的元素复制到新的内存空间中。这个过程可能会导致原有的迭代器失效,因为它们指向的内存地址已经发生变化。

  2. 删除元素:当从vector中删除元素时,如果删除的不是最后一个元素,会将后面的元素向前移动填补空缺,这也会导致原有的迭代器失效。

  3. 插入元素:当在vector中插入元素时,会将插入位置后面的元素向后移动,同样会导致原有的迭代器失效。

  4. 内存重新分配:当vector的容量增加时,会重新分配内存空间,并将原有的元素复制到新的内存空间中。这个过程会导致所有的迭代器失效。

简易的vector

由于现在学习的知识有限,所以我们大致做了个简单的vector

template<class T>
	
	class my_vector {

	public:
		typedef T* iterator;	// iterator表示某个类型的指针,作为迭代器
		typedef const T* const_iterator;


		// 迭代器
		iterator begin() {
			return _start;
		}
		iterator end() {
			return _finish;
		}

		// vector的返回参数
		size_t capacity() const {		// vector的容量

			return _end_of_storage - _start;
		}
		size_t size() const {		// 返回vector的大小

			return _finish - _start;
		}

		// 交换函数
		void swap(my_vector<T>& v) {

			std::swap(_start, v._start);
			std::swap(_finish, v._finish);
			std::swap(_end_of_storage, v._end_of_storage);
		}

		// 判空
		bool empty() const {	// 为空返回非0

			return _finish == _start;
		}

		// 重载[] 
		T& operator[](size_t position) {

			assert(position < size());
			return _start[position];
		}
		// 重载=
		my_vector<T>& operator=(my_vector<T> v) {	// 传入临时拷贝,防止被修改,用const类型就不能swap

			swap(v);	// 用临时拷贝来替代修改
			return *this;
		}

		// 主要成员函数

		// 构造与析构
		my_vector()
			:_start(nullptr)
			, _finish(nullptr)
			, _end_of_storage(nullptr)
		{

		}
		my_vector(const my_vector<T>& v)
			:_start(nullptr)
			, _finish(nullptr)
			, _end_of_storage(nullptr)
		{
			reserve(v.capacity());
			for (auto& e : v) {	// 将数据插入

				push_back(e);
			}
		};
		template<class inputIterator>
		my_vector(inputIterator first, inputIterator end) {	// 通过迭代器拷贝构造某一部分

			while (first != end) {

				push_back(*first);
				first++;
			}
		}
		my_vector(int n, const T& data = T()) {		// 防止传入的为(10,0)调用模版(上一个构造函数)

			reserve(n);
			for (int i = 0; i < n; i++) {

				push_back(data);
			}
		}
		my_vector(size_t n, const T& data = T()) {

			reserve(n);
			for (size_t i = 0; i < n; i++) {

				push_back(data);
			}
		}


		~my_vector() {	// 析构

			delete[] _start;
			_start = _finish = _end_of_storage = nullptr;
		}



		void reserve(size_t n) {	// 扩容函数

			if (n > capacity()) {

				size_t _size = size();
				T* tmp = new T[n];
				if (_start) {
					// 手动拷贝
					for (size_t i = 0; i < _size; i++) {

						tmp[i] = _start[i];
					}
					delete[] _start;
				}

				_start = tmp;
				_finish = _start + _size;	// 这里有个隐藏的坑,_size这个变量取消,然后换size()
				_end_of_storage = _start + n;
			}
		}	
		void resize(size_t n, const T& data = T()) {	// 大小重置

			if (n <= size())
				_finish = _start + n;
			else {
				
				reserve(n);	// 借助reserve()判断大小大于容量的话会扩容,小于容量不会扩容
				while (_finish < _start + n) {

					*_finish = data;
					_finish++;
				}
			}
				
		}

		// 插入
		void push_back(const T& data) { // 插入单个数据

			if (_finish == _end_of_storage) {

				reserve(capacity() == 0 ? 4 : capacity() * 2);
			}

			*_finish = data;
			_finish++;

		}
		void insert(iterator postion, const T& data) {

			assert(postion >= _start && postion <= _finish);
			
			size_t pos_len = postion - _start;	// 记录相对位置,防止扩容后postion失效
			
			if (_finish == _end_of_storage) {

				reserve(capacity() == 0 ? 4 : capacity() * 2);
				postion = _start + pos_len;		// 扩容产生新的postion
			}

			// 注意扩容可能导致迭代器失效

			iterator flag = _finish - 1;	
			while (flag >= postion) {

				*(flag + 1) = *flag;
				flag--;
			}
			*postion = data;
			_finish++;

		}

		// 删除
		iterator erase(iterator postion) {
			// 注意当删除了postion时可能会导致迭代器失效,即前后地址不连续,导致无法找到
			// 连续使用的时候需要保留postion前后的迭代器地址

			assert(postion >= _start && postion < _finish);
			iterator flag = postion + 1;
			
			while (flag < _finish) {
				*(flag - 1) = *flag;
				flag++;
			}
			_finish--;
			// 这里返回了
			return postion;
		}
		void clear() {

			_finish = _start;
		}


		// 查的话通过库中的find函数
		T& at(size_t n) {

			assert(n < size());
			return _start[_start + n];
		}



	private:
		// 数组的头,  相当于 type* _array 
		iterator _start;
		// 数组有效数据的尾巴,  相当于 _array + _size
		iterator _finish;
		// 数组空间的尾巴,  相当于_array + _capacity
		iterator _end_of_storage;
	

	};

测试函数

// 测试迭代
void test_vector1() {

	my_vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	v.push_back(2);
	v.push_back(1);

	for (size_t i = 0; i < v.size(); i++) {

		cout << v[i] << " ";
	}
	cout << endl;

	my_vector<int>::iterator it = v.begin();
	while (it != v.end()) {
	
		*it = 10;
		cout << *it << " ";
		++it;
	}
	cout << endl;

	for (auto e : v) {
	
		cout << e << " ";
	}
	cout << endl;

}
// 测试resize
void test_vector2() {

	my_vector<int*> v1;
	v1.resize(1);

	my_vector<string> v2;
	//v2.resize(10, string("xxx"));
	v2.resize(10, "xxx");

	for (auto e : v1) {
	
		cout << e << " ";
	}
	cout << endl;

	for (auto e : v2) {
	
		cout << e << " ";
	}
	cout << endl;
}
// 测试insert
void test_vector3() {	

	my_vector<int> 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.push_back(7);

	for (auto e : v) {

		cout << e << " ";
	}
	cout << endl;

	my_vector<int>::iterator it = v.begin() + 2;
	v.insert(it, 30);
	for (auto e : v) {
	
		cout << e << " ";
	}
	cout << endl;

	//v.insert(v.begin(), 30);
	v.insert(v.begin() + 3, 30);	// 85, 86行不能同时,迭代器会失效
	for (auto e : v) {
	
		cout << e << " ";
	}
	cout << endl;
}
// 测试erase
void test_vector4() {

	my_vector<int> 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.push_back(7);

	for (auto e : v) {

		cout << e << " ";
	}
	cout << endl;

	auto pos = v.begin();
	v.erase(pos);

	for (auto e : v) {
	
		cout << e << " ";
	}
	cout << endl;

	v.erase(v.begin() + 3);
	for (auto e : v) {
	
		cout << e << " ";
	}
	cout << endl;

}



	//void test_vector5()
	//{
	//	// 1 2 3 4 5
	//	// 1 2 3 4 5 6
	//	// 2 2 3 4 5
	//	std::vector<int> 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);

	//	for (auto e : v)
	//	{
	//		cout << e << " ";
	//	}
	//	cout << endl;

	//	auto it = v.begin();
	//	while (it != v.end())
	//	{
	//		// vs2019进行强制检查,erase以后认为it失效了,不能访问,访问就报错
	//		if (*it % 2 == 0)
	//		{
	//			v.erase(it);
	//		}

	//		++it;
	//	}

	//	for (auto e : v)
	//	{
	//		cout << e << " ";
	//	}
	//	cout << endl;
	//}
// 测试迭代器失效
void test_vector5() {	// 与上面部分进行对比

	//std::vector<int> v;
	my_vector<int> v;

	v.push_back(1);		// 测试案例 1,2,3,4,5
	v.push_back(2);		// 2,3,2,2,4
	v.push_back(3);
	v.push_back(4);
	v.push_back(4);
	v.push_back(5);
	v.push_back(6);

	for (auto e : v) {
	
		cout << e << " ";
	}
	cout << endl;

	auto it = v.begin();
	while (it != v.end()) {
	
		if (*it % 2 == 0)
			it = v.erase(it);
		else	
			++it;
	}

	for (auto e : v) {
	
		cout << e << " ";
	}
	cout << endl;

}
// 测试vector里面放string
void test_vector6() {
	my_vector<string> v;
	v.push_back("111111111111111111111");
	v.push_back("111111111111111111111");
	v.push_back("111111111111111111111");
	v.push_back("111111111111111111111");
	v.push_back("111111111111111111111");


	for (auto e : v)
	{
		cout << e << " ";
	}
	cout << endl;
}
// 测试拷贝构造和等号重载
void test_vector7() {
	my_vector<int> v1;
	v1.push_back(1);
	v1.push_back(1);
	v1.push_back(1);
	v1.push_back(1);
	v1.push_back(1);

	my_vector<int> v2(v1);

	for (auto e : v1)
	{
		cout << e << " ";
	}
	cout << endl;

	for (auto e : v2)
	{
		cout << e << " ";
	}
	cout << endl;

	my_vector<int> v3;
	v3.push_back(10);
	v3.push_back(20);
	v3.push_back(30);
	v3.push_back(40);

	v1 = v3;

	for (auto e : v1)
	{
		cout << e << " ";
	}
	cout << endl;
}

void test_vector8() {
	//vector<int> v0(10, 0);
	my_vector<string> v1(10, "xxxx");

	for (auto e : v1)
	{
		cout << e << " ";
	}
	cout << endl;

	my_vector<int> v2;
	v2.push_back(10);
	v2.push_back(20);
	v2.push_back(30);
	v2.push_back(40);

	my_vector<int> v3(v2.begin(), v2.end());

	string str("hello world");
	my_vector<int> v4(str.begin(), str.end());
	for (auto e : v3)
	{
		cout << e << " ";
	}
	cout << endl;

	for (auto e : v4)
	{
		cout << e << " ";
	}
	cout << endl;
}



最终代码

写到这里vector大致就结束了,剩下的反向迭代器以及部分的高级用法内容后续补上

#pragma once
#include<iostream>
#include<string>
#include<assert.h>
#include <initializer_list>
using namespace std;

namespace zhong{


	template<class iterator, class Reference, class Pointer>
	struct Reverse_iterator {

		typedef Reverse_iterator<iterator, Reference, Pointer> self;

		Reverse_iterator(iterator it)	:_it(it){}

		self& operator++() {
			--_it;
			return *this;
		}
		self& operator--() {

			++_it;
			return *this;
		}
		Reference operator*() const {
			iterator cur = _it;
			return *(--cur);
		}
		Pointer operator->() const { return &(operator*()); }


		bool operator==(const self& s) { return _it == s._it; }
		bool operator!=(const self& s) { return  _it != s._it; }


		iterator _it;
	};




	template<class T>
	class my_vector {

	public:
		typedef T* iterator;	// iterator表示某个类型的指针,作为迭代器
		typedef const T* const_iterator;
		typedef Reverse_iterator<iterator, T&, T*> reverse_iterator;
		typedef Reverse_iterator<const_iterator,const T&,const T*> const_reverse_iterator;

		// 迭代器
		iterator begin() { return _start; }
		iterator end() { return _finish; }

		const_iterator begin() const { return _start; }
		const_iterator end() const { return _finish; }

		// 反向迭代器
		reverse_iterator rbegin() { return reverse_iterator(_finish); }
		reverse_iterator rend() { return reverse_iterator(_start); }

		const_reverse_iterator rbegin() const { return const_reverse_iterator(_finish); }
		const_reverse_iterator rend() const { return const_reverse_iterator(_start); }

		// vector的返回参数
		size_t capacity() const { return _end_of_storage - _start; }
		size_t size() const { return _finish - _start; }

		// 交换函数
		void swap(my_vector<T>& v) {

			std::swap(_start, v._start);
			std::swap(_finish, v._finish);
			std::swap(_end_of_storage, v._end_of_storage);
		}

		// 判空
		bool empty() const {	// 为空返回非0

			return _finish == _start;
		}

		// 重载[] 
		T& operator[](size_t position) {

			assert(position < size());
			return _start[position];
		}
		// 重载=
		my_vector<T>& operator=(my_vector<T> v) {	// 传入临时拷贝,防止被修改,用const类型就不能swap

			swap(v);	// 用临时拷贝来替代修改
			return *this;
		}

		// 主要成员函数

		// 构造与析构
		my_vector()
			:_start(nullptr)
			, _finish(nullptr)
			, _end_of_storage(nullptr)
		{

		}
		my_vector(const my_vector<T>& v)
			:_start(nullptr)
			, _finish(nullptr)
			, _end_of_storage(nullptr)
		{
			reserve(v.capacity());
			for (size_t i = 0; i < v.size(); i++) {

				push_back(v._start[i]);
			}
		};
		template<class inputIterator>
		my_vector(inputIterator first, inputIterator end)	{	// 通过迭代器拷贝构造某一部分

			while (first != end) {

				push_back(*first);
				first++;
			}
		}
		my_vector(int n, const T& data = T()) {		// 防止传入的为(10,0)调用模版(上一个构造函数)

			reserve(n);
			for (int i = 0; i < n; i++) {

				push_back(data);
			}
		}
		my_vector(size_t n, const T& data = T()) {

			reserve(n);
			for (size_t i = 0; i < n; i++) {

				push_back(data);
			}
		}

		~my_vector() {	// 析构

			delete[] _start;
			_start = _finish = _end_of_storage = nullptr;
		}



		void reserve(size_t n)  {	// 扩容函数

			if (n > capacity()) {

				size_t _size = size();
				T* tmp = new T[n];
				if (_start) {
					// 手动拷贝
					for (size_t i = 0; i < _size; i++) {

						tmp[i] = _start[i];
					}
					delete[] _start;
				}

				_start = tmp;
				_finish = _start + _size;	// 这里有个隐藏的坑,_size这个变量取消,然后换size()
				_end_of_storage = _start + n;
			}
		}	
		void resize(size_t n, const T& data = T()) {	// 大小重置

			if (n <= size())
				_finish = _start + n;
			else {
				
				reserve(n);	// 借助reserve()判断大小大于容量的话会扩容,小于容量不会扩容
				while (_finish < _start + n) {

					*_finish = data;
					_finish++;
				}
			}
				
		}

		// 插入
		void push_back(const T& data) { // 插入单个数据

			if (_finish == _end_of_storage) {

				reserve(capacity() == 0 ? 4 : capacity() * 2);
			}

			*_finish = data;
			_finish++;

		}
		void insert(iterator postion, const T& data) {

			assert(postion >= _start && postion <= _finish);
			
			size_t pos_len = postion - _start;	// 记录相对位置,防止扩容后postion失效
			
			if (_finish == _end_of_storage) {

				reserve(capacity() == 0 ? 4 : capacity() * 2);
				postion = _start + pos_len;		// 扩容产生新的postion
			}

			// 注意扩容可能导致迭代器失效

			iterator flag = _finish - 1;	
			while (flag >= postion) {

				*(flag + 1) = *flag;
				flag--;
			}
			*postion = data;
			_finish++;

		}

		// 删除
		iterator erase(iterator postion) {
			// 注意当删除了postion时可能会导致迭代器失效,即前后地址不连续,导致无法找到
			// 连续使用的时候需要保留postion前后的迭代器地址

			assert(postion >= _start && postion < _finish);
			iterator flag = postion + 1;
			
			while (flag < _finish) {
				*(flag - 1) = *flag;
				flag++;
			}
			_finish--;
			// 这里返回了
			return postion;
		}
		void clear() {

			_finish = _start;
		}


		// 查的话通过库中的find函数
		T& at(size_t n) {

			assert(n < size());
			return _start[_start + n];
		}



	private:
		// 数组的头,  相当于 type* _array 
		iterator _start;
		// 数组有效数据的尾巴,  相当于 _array + _size
		iterator _finish;
		// 数组空间的尾巴,  相当于_array + _capacity
		iterator _end_of_storage;
	

	};

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值