【C++】vector的模拟实现

一:默认成员函数的模拟实现

二:多种打印的模拟实现

三:reserve与resize的模拟实现

四:插入/删除元素的模拟实现

五:迭代器失效的解决方法

六:多重拷贝的问题与解决方法

//////

什么是vector:

vector是是表示大小可以更改的数组的序列容器。

就像数组一样,vector对其元素使用连续的存储位置,这意味着也可以使用指向其元素的常规指针上的偏移量来访问它们的元素,并且与在数组中一样高效;在此,我模拟实现具有泛型模板的vector

//////

一:默认成员函数的模拟实现

1:多种构造函数:

通过对STL库的构造函数的声明与对源码的简单分析,我们可以得出一点有用的结论:

1:构造函数大概有无参构造函数,有参构造函数,以及模板构造函数等好几种类型的构造函数

2:大概有三个指针来指向vector,_start指向vector所存储的数据开头

                                                               _finish指向有效数据的结尾的下一个位置

                                                                  _end_of_storage则指向整个数据的结尾,

具体各种构造函数的代码如下所示:

namespace MKL//因为自己模拟实现,怕与库中冲突,所以将模拟实现封在一个命名空间中;
{
	template<class T>//因为模拟实现泛型模板的vector,所以用模板;
	class vector
	{
	public:
        //无参构造函数:
		vector()//初始化列表:
			:_start(nullptr)
			, _finish(nullptr)
			, _end_of_stroage(nullptr)
		{

		}

        //无符号有参构造函数:
		vector(size_t n,const T& temp=T())//T()是匿名构造,生命周期只有所在行,加上const,延长其生命周期到引用对象作用域结束;

            //初始化列表:
			:_start(nullptr)
			, _finish(nullptr)
			, _end_of_stroage(nullptr)
		{
			reserve(n);//开辟空间;
			for (size_t i = 0; i < n; i++)
			{
				push_back(temp);//一个一个插入构造;
			}
		}

        
        //有符号有参构造函数:
		vector(int n, const T& temp = T())//T()是匿名构造,生命周期只有所在行,加上const,延长其生命周期到引用对象作用域结束;

            //初始化列表:
			:_start(nullptr)
			, _finish(nullptr)
			, _end_of_stroage(nullptr)
		{
			reserve(n);
			for (int i = 0; i < n; i++)
			{
				push_back(temp);
			}
		}

        //模板构造函数:
		template<class InputIterator>
		vector(InputIterator first, InputIterator last)
			:_start(nullptr)
			, _finish(nullptr)
			, _end_of_stroage(nullptr)
		{
			while (first != last)
			{
				push_back(*first);
				++first;
			}
		}

	private:
		iterator _start;
		iterator _finish;
		iterator _end_of_stroage;
	};

由于c++11推出当给内置类型缺省值时,可以将缺省值当初始化列表使用时;我们可以稍微简化一下代码,使每一种构造函数不必都带有初始化列表:

namespace MKL
{
	template<class T>
	class vector
	{
	public:
        //无参构造函数:
		vector()//初始化列表:

		{
		}

        //无符号有参构造函数:
		vector(size_t n,const T& temp=T())

		{
			reserve(n);//开辟空间;
			for (size_t i = 0; i < n; i++)
			{
				push_back(temp);//一个一个插入构造;
			}
		}

        
        //有符号有参构造函数:
		vector(int n, const T& temp = T())

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

        //模板构造函数:
		template<class InputIterator>
		vector(InputIterator first, InputIterator last)
			:_start(nullptr)
			, _finish(nullptr)
			, _end_of_stroage(nullptr)
		{
			while (first != last)
			{
				push_back(*first);
				++first;
			}
		}

	private:
        //内置类型给其缺省值;初始化为空
		iterator _start=nullptr;
		iterator _finish=nullptr;
		iterator _end_of_stroage=nullptr;
	};

这里放一些调用构造函数的例子,便于更好的理解:

//各种构造函数:
	void test_vector5()
	{
		//vector(size_t n, const T& temp=T()),使用size_t版的构造函数;
		vector<int> v1(10u, 1);
		for (auto e : v1)
		{
			cout << e << " ";
		}
		cout << endl;

		//vector(int n, const T& temp=T()),使用int版的构造函数;
		vector<int> v2(10, 1);
		for (auto e : v2)
		{
			cout << e << " ";
		}
		cout << endl;

		//vector(InputIterator first, InputIterator last);使用模板的构造函数;
		string s1("aaabbbccc");//char类型转化为整形
		vector<int> v4(s1.begin(), s1.end());
		for (auto e : v4)
		{
			cout << e << " ";
		}
		cout << endl;

		vector(InputIterator first, InputIterator last);可以使用数组,本质还是指针:
		int arr[] = { 10,20,30,40,50};//原生指针,
		vector<int> v5(arr, arr + 5);
		for (auto e : v5)
		{
			cout << e << " ";
		}
		cout << endl;


		v2.insert(v2.begin(), 10);
		v2.insert(v2.begin() + 3, 3);
		v2.insert(v2.begin(), 2);
		
		//排序:
		sort(v2.begin(), v2.end());
		for (auto e : v2)
		{
			cout << e << " ";
		}
		cout << endl;
	}

//////

二:多种打印的模拟实现

我们如何访问cvctor容器内存储的元素呢?

1:迭代器实现(2:语法糖实现(底层仍然是迭代器));3;下标 [ ] 实现   

 4:类外函数实现(也是调用类中的成员函数(迭代器,下标[ ]),但是成员函数是加const的);

namespace MKL
{
	template<class T>
	class vector
	{
	public:
		typedef T* iterator;
		typedef T* const_iterator;

		iterator begin()
		{
			return _start;
		}

		iterator end()
		{
			return _finish;
		}

		const_iterator begin()const
		{
			return _start;
		}

		const_iterator end()const
		{
			return _finish;
		}

        T& operator[](size_t pos)
		{
			assert(pos < size());
			return _start[pos];
		}

		const T& operator[](size_t pos)const
		{
			assert(pos < size());
			return _start[pos];
		}

	private:
		iterator _start;
		iterator _finish;
		iterator _end_of_stroage;
	};


    //类外打印函数:(调用下标,或者迭代器,语法糖)
	void print(const vector<int>& v)
	{
		for (size_t i = 0; i < v.size(); i++)
		{
			cout << v[i] << " ";
		}
		cout << endl;

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

		for (auto e : v)
		{
			cout << e << " ";
		}
	}
	void test_vector2()
	{
		vector<int> v2;

        //尾插几个元素进去;

		v2.push_back(1);
		v2.push_back(2);
		v2.push_back(3);
		v2.push_back(4);
		v2.push_back(5);

        //利用下标打印
		for (size_t i = 0; i < v2.size(); i++)
		{
			cout << v2[i] << " ";
		}
		cout << endl;

        //迭代器打印:
		vector<int>::iterator it = v2.begin();
		while (it != v2.end())
		{
			cout << *(it) << " ";
			it++;
		}
		cout << endl;

        //语法糖(底层是迭代器)打印:
		for (auto e : v2)
		{
			cout << e << " ";
		}
		cout << endl;

        //调用类外打印函数;
		print(v2);
	}

//////

三:reserve与resize的模拟实现

通过库中的定义我们可以认识到,

reserve只改变vector容器的capacity(容量);

resize可以改变vector容器的size(元素个数),capacity(容量);

        size_t size()const
		{
			return _finish - _start;
		}

		size_t capacity()const
		{
			return _end_of_stroage - _start;
		}

		
		//void reserve(size_t n)
		//{
		//	if (n > capacity())
		//	{
		//		size_t sz = size();
		//		T* temp = new T[n];
		//		if (_start)
		//		{
                    //memcpy是浅拷贝,所以在有深拷贝的地方不能使用;
		//			memcpy(temp, _start, sizeof(T) * size());
		//			delete[] _start;
		//		}
		//		_start = temp;
		//		_finish = _start + sz;
		//		_end_of_stroage = _start + n;
		//	}
		//}

		void reserve(size_t n)
		{
			if (n > capacity())//防止缩容,导致数据丢失;
			{
				size_t sz = size();//先记录_finish与_start的相对位置,防止找不到;
				T* temp = new T[n];//创建临时的容器;
				if (_start)//如果原容器不为空
				{
                    一个一个拷贝:
					for (size_t i = 0; i < size(); ++i)
					{
						temp[i] = _start[i];
					}
					delete[] _start;//释放之前的空间;
				}
				_start = temp;//再将临时容器赋给原容器;
				_finish = _start + sz;//通过刚才记录的相对位置找到新空间内_finish的位置;
				_end_of_stroage = _start + n;//更新_end_of_stroage;
			}
		}

		void resize(size_t n, T x=T())//匿名构造,因为是泛型模板,不知道要初始化成什么样;
                                      //所以匿名构造适用于各种类型;
		{
			if (n < size())//如果小于现有元素个数,则是缩容;
			{
				_finish = _start + n;
			}
			else//否则则是扩容;
			{
				if (n > capacity())//空间不够开空间;
				{
					reserve(n);
				}
				size_t end = size();//创建临时变量
				while (end < n)//如果元素个数不到要求的元素个数;
				{
					_start[end] = x;//初始化元素;
					++end;
				}
				_finish =_start+n;//更新_finish;
			}
		}

//////

四:插入/删除元素的模拟实现

1:尾插与尾删:

        //尾插:
        void push_back(const T& x)
		{
			if (_finish == _end_of_stroage)//如果满了或者都为空;
			{
				reserve(capacity() == 0 ? 4 : capacity() * 2);
			}
			*(_finish) = x;//在_finish插入;
			++_finish;
		}


        //尾删:
		void pop_back()
		{
			assert(size() > 0);//断言一下,防止已经删完了还删;
			--_finish;//控制_finish便实现尾删;
		}

///

2:任意位置的插入(insert)与删除(erase):

 通过库中的声明知道,insert与erase是支持迭代器来找位置插入/删除元素的,也可以用模板;

		void insert(iterator pos, const T& x)
		{
            //断言迭代器POS是否有效;
			assert(pos >= _start);
			assert(pos <= _finish);
			if (_finish == _end_of_stroage)//是否需要扩容;
			{
				reserve(capacity() == 0 ? 4 : capacity() * 2);
			}
			iterator end = _finish-1;//开始向后挪动数据
			while (end >= pos)
			{
				*(end + 1) = *(end);
				--end;
			}
			*pos = x;
			++_finish;//更新_finish
		}

		void erase(iterator pos)
		{
            //断言迭代器POS是否有效;
			assert(pos >= _start);
			assert(pos < _finish);
			iterator end = pos + 1;//开始向前挪动数据
			while (end != _finish)
			{
				*(end-1) = *(end);
				++end;
			}
			--_finish;//更新_finish
			
		}

【N】:当我们写好insert与erase时,在调用时会发现一个很严重的问题,那就是迭代器失效,所以上面的insert与erase是不完整,有问题的;

//////

五:迭代器失效的解决方法

迭代器的两种失效问题:

第一种(pos迭代器失效):因为扩容,调用reserve时需要释放原空间,而迭代器pos指向的是原空间上的位置,由于原空间被释放,pos指针也随着失效了;

第二种(pos迭代器出函数销毁):调用insert时,当想修改插入的元素的大小时,不能修改,因为pos迭代器是临时变量,形参的改变不能影响实参; 调用erase时,由于删除时需要挪动,当不记录下pos迭代器的位置,容易跑丢,造成段错误;


		iterator insert(iterator pos, const T& x)//第二种迭代器失效:由于POS是临时对象,不能使用引用,出作用域销毁;
		{
			assert(pos >= _start);
			assert(pos <= _finish);
			if (_finish == _end_of_stroage)
			{
				//第一种迭代器失效:扩容时失效:
				size_t len = pos - _start;//解决方法:为了防止扩容时迭代器的相对位置失效,先记录一下POS的相对位置;
				reserve(capacity() == 0 ? 4 : capacity() * 2);
				pos = _start + len;//扩完容后再通过相对位置找到POS;
			}
			iterator end = _finish-1;
			while (end >= pos)
			{
				*(end + 1) = *(end);
				--end;
			}
			*pos = x;
			++_finish;
			return pos;//解决方法:通过返回值返回POS的地址;
		}

		iterator erase(iterator pos)//迭代器失效:删除就向后走,容易走过形成段错误;
		{
			assert(pos >= _start);
			assert(pos < _finish);
			iterator end = pos + 1;
			while (end != _finish)
			{
				*(end-1) = *(end);
				++end;
			}
			--_finish;
			return pos;//解决方法:通过返回值接受pos的下标,当删除后返回当前下标;不删除时向后走;
		}

这里放一段调用insert与erase的使用例子,便于更好的理解:
 

void test_vector4()//插入几个元素,同时删除其中的偶数
	{
		vector<int> v4;
		v4.push_back(100);
		v4.push_back(2);
		v4.push_back(30);
		v4.push_back(4);
		v4.push_back(5);
		v4.insert(v4.begin(), 10);
		for (auto e : v4)
		{
			cout << e << " ";
		}
		cout << endl;
		auto pos = find(v4.begin(), v4.end(),4);//算法
		if (pos != v4.end())
		{
			v4.insert(pos, 10);
		}
		for (auto e : v4)
		{
			cout << e << " ";
		}
		cout << endl;
		(*pos)++;
		for (auto e : v4)
		{
			cout << e << " ";
		}
		cout << endl;

		vector<int>::iterator it = v4.begin();
		while (it != v4.end())
		{
			//错误代码:不论删除还是不删除,都往后走且没有接受pos下标的位置,当删除最后一个元素时,下标未定义;
			//if (*(it) % 2 == 0)
			//{
			//	v4.erase(it);
			//}
			//++it;
			if (*(it) % 2 == 0)
			{
				it = v4.erase(it);
			}
			else
			{
				++it;
			}
		}
		for (auto e : v4)
		{
			cout << e << " ";
		}
		cout << endl;
	}

//////

六:多重拷贝的问题与解决方法

当出现一层拷贝的时候我们还是比较容易搞定,比如:vecrot<int> v1内有1,2,3,4,四个元素;

当调用拷贝构造时,vector<int> v2=v1,这就是一层拷贝,此时,使用memcpy来拷贝数据;

		只适用于一层的深拷贝,当两层的拷贝时不适用;
		vector(const vector<T>& v)
			:_start(nullptr)
			, _finish(nullptr)
			, _end_of_stroage(nullptr)
		{
			reserve(v.capacity());
			memcpy(_start, v._start, sizeof(T) * v.size());
			_finish = _start + v.size();
			_end_of_stroage = _start + v.capacity();
		}

但是当出现类似vector<string>  与vector<vector<int>> 这样的像是嵌套使用的容器时,一层深拷贝就显得乏力了;此时memcpy就是一种浅拷贝,需要更深层次的拷贝,利用赋值重载可以解决,但是默认的赋值重载也是浅拷贝,我们需要自己写赋值重载,同时通过交换函数swap解决赋值重载的问题;

            vector(const vector<T>& v)
			:_start(nullptr)
			, _finish(nullptr)
			, _end_of_stroage(nullptr)
		{

			reserve(v.capacity());
			for (size_t i = 0; i < v.size(); ++i)
			{
				_start[i] = v._start[i];//由于没有写赋值重载,所以调用默认赋值重载,但是会引发浅拷贝;
			}
			_finish = _start + v.size();
			_end_of_stroage = _start + v.capacity();
		}

		
		//拷贝构造中的赋值重载问题可通过交换解决浅拷贝问题;
		void swap(vector<T>& v)
		{
			std::swap(_start, v._start);
			std::swap(_finish, v._finish);
			std::swap(_end_of_stroage, v._end_of_stroage);
		}
		vector<T>& operator=(vector<T> v)
		{
			swap(v);
			return *this;
		}

//////

至此,这是我对vector类的一些简单的模拟实现,如有错误,请各位不吝赐教!

同时,我将会把我自己模拟实现的vector类的全部代码放在下方,请各位大佬指正!

#include <assert.h>
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;

namespace MKL
{
	template<class T>
	class vector
	{
	public:
		typedef T* iterator;
		typedef T* const_iterator;

		vector()
			:_start(nullptr)
			, _finish(nullptr)
			, _end_of_stroage(nullptr)
		{

		}
		vector(size_t n,const T& temp=T())//T()是匿名构造,生命周期只有所在行,加上const,延长其生命周期到引用对象作用域结束;
			:_start(nullptr)
			, _finish(nullptr)
			, _end_of_stroage(nullptr)
		{
			reserve(n);
			for (size_t i = 0; i < n; i++)
			{
				push_back(temp);
			}
		}

		vector(int n, const T& temp = T())//T()是匿名构造,生命周期只有所在行,加上const,延长其生命周期到引用对象作用域结束;
			:_start(nullptr)
			, _finish(nullptr)
			, _end_of_stroage(nullptr)
		{
			reserve(n);
			for (int i = 0; i < n; i++)
			{
				push_back(temp);
			}
		}

		template<class InputIterator>
		vector(InputIterator first, InputIterator last)
			:_start(nullptr)
			, _finish(nullptr)
			, _end_of_stroage(nullptr)
		{
			while (first != last)
			{
				push_back(*first);
				++first;
			}
		}

		//只适用于一层的深拷贝,当两层的拷贝时不适用;
		//vector(const vector<T>& v)
		//	:_start(nullptr)
		//	, _finish(nullptr)
		//	, _end_of_stroage(nullptr)
		//{
		//	reserve(v.capacity());
		//	memcpy(_start, v._start, sizeof(T) * v.size());
		//	_finish = _start + v.size();
		//	_end_of_stroage = _start + v.capacity();
		//}

		vector(const vector<T>& v)
			:_start(nullptr)
			, _finish(nullptr)
			, _end_of_stroage(nullptr)
		{

			reserve(v.capacity());
			for (size_t i = 0; i < v.size(); ++i)
			{
				_start[i] = v._start[i];//由于没有写赋值重载,所以调用默认赋值重载,但是会引发浅拷贝;
			}
			_finish = _start + v.size();
			_end_of_stroage = _start + v.capacity();
		}
		
		//拷贝构造中的赋值重载问题可通过交换解决浅拷贝问题;
		void swap(vector<T>& v)
		{
			std::swap(_start, v._start);
			std::swap(_finish, v._finish);
			std::swap(_end_of_stroage, v._end_of_stroage);
		}
		vector<T>& operator=(vector<T> v)
		{
			swap(v);
			return *this;
		}

		~vector()
		{
			delete[] _start;
			_start = _finish = _end_of_stroage = nullptr;
		}

		size_t size()const
		{
			return _finish - _start;
		}

		size_t capacity()const
		{
			return _end_of_stroage - _start;
		}

		iterator begin()
		{
			return _start;
		}

		iterator end()
		{
			return _finish;
		}

		const_iterator begin()const
		{
			return _start;
		}

		const_iterator end()const
		{
			return _finish;
		}


		//void reserve(size_t n)
		//{
		//	if (n > capacity())
		//	{
		//		size_t sz = size();
		//		T* temp = new T[n];
		//		if (_start)
		//		{
		//			memcpy(temp, _start, sizeof(T) * size());
		//			delete[] _start;
		//		}
		//		_start = temp;
		//		_finish = _start + sz;
		//		_end_of_stroage = _start + n;
		//	}
		//}

		void reserve(size_t n)
		{
			if (n > capacity())
			{
				size_t sz = size();
				T* temp = new T[n];
				if (_start)
				{
					for (size_t i = 0; i < size(); ++i)
					{
						temp[i] = _start[i];
					}
					delete[] _start;
				}
				_start = temp;
				_finish = _start + sz;
				_end_of_stroage = _start + n;
			}
		}

		void resize(size_t n, T x=T())
		{
			if (n < size())
			{
				_finish = _start + n;
			}
			else
			{
				if (n > capacity())
				{
					reserve(n);
				}
				size_t end = size();
				while (end < n)
				{
					_start[end] = x;
					++end;
				}
				_finish =_start+n;
			}
		}

		//void insert(iterator pos, const T& x)
		//{
		//	//断言迭代器POS是否有效;
		//	assert(pos >= _start);
		//	assert(pos <= _finish);
		//	if (_finish == _end_of_stroage)//是否需要扩容;
		//	{
		//		reserve(capacity() == 0 ? 4 : capacity() * 2);
		//	}
		//	iterator end = _finish - 1;//开始向后挪动数据
		//	while (end >= pos)
		//	{
		//		*(end + 1) = *(end);
		//		--end;
		//	}
		//	*pos = x;
		//	++_finish;//更新_finish
		//}

		//void erase(iterator pos)
		//{
		//	//断言迭代器POS是否有效;
		//	assert(pos >= _start);
		//	assert(pos < _finish);
		//	iterator end = pos + 1;//开始向前挪动数据
		//	while (end != _finish)
		//	{
		//		*(end - 1) = *(end);
		//		++end;
		//	}
		//	--_finish;//更新_finish

		//}


		iterator insert(iterator pos, const T& x)//第二种迭代器失效:由于POS是临时对象,不能使用引用,出作用域销毁;
		{
			assert(pos >= _start);
			assert(pos <= _finish);
			if (_finish == _end_of_stroage)
			{
				//第一种迭代器失效:扩容时失效:
				size_t len = pos - _start;//解决方法:为了防止扩容时迭代器的相对位置失效,先记录一下POS的相对位置;
				reserve(capacity() == 0 ? 4 : capacity() * 2);
				pos = _start + len;//扩完容后再通过相对位置找到POS;
			}
			iterator end = _finish-1;
			while (end >= pos)
			{
				*(end + 1) = *(end);
				--end;
			}
			*pos = x;
			++_finish;
			return pos;//解决方法:通过返回值返回POS的地址;
		}

		iterator erase(iterator pos)//迭代器失效:删除就向后走,容易走过形成段错误;
		{
			assert(pos >= _start);
			assert(pos < _finish);
			iterator end = pos + 1;
			while (end != _finish)
			{
				*(end-1) = *(end);
				++end;
			}
			--_finish;
			return pos;//解决方法:通过返回值接受pos的下标,当删除后返回当前下标;不删除时向后走;
		}

		void push_back(const T& x)
		{
			if (_finish == _end_of_stroage)
			{
				reserve(capacity() == 0 ? 4 : capacity() * 2);
			}
			*(_finish) = x;
			++_finish;
		}

		void pop_back()
		{
			assert(size() > 0);
			--_finish;
		}

		T& operator[](size_t pos)
		{
			assert(pos < size());
			return _start[pos];
		}

		const T& operator[](size_t pos)const
		{
			assert(pos < size());
			return _start[pos];
		}

	private:
		iterator _start;
		iterator _finish;
		iterator _end_of_stroage;

		//iterator _start=nullptr;
		//iterator _finish=mullptr;
		//iterator _end_of_stroage=nullptr;
	};


	void test_vector1()
	{
		vector<int> v1;
		v1.push_back(1);
		v1.push_back(2);
		v1.push_back(3);
		v1.push_back(4);
		v1.push_back(5);
		for (auto e : v1)
		{
			cout << e << " ";
		}
		cout << endl;
		v1.pop_back();
		v1.pop_back();
		v1.pop_back();
		for (auto e : v1)
		{
			cout << e << " ";
		}
		cout << endl;
		v1.pop_back();
		v1.pop_back();
		v1.pop_back();

	}


	void print(const vector<int>& v)
	{
		for (size_t i = 0; i < v.size(); i++)
		{
			cout << v[i] << " ";
		}
		cout << endl;

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

		for (auto e : v)
		{
			cout << e << " ";
		}
	}
    //各种打印
	void test_vector2()
	{
		vector<int> v2;
		v2.push_back(1);
		v2.push_back(2);
		v2.push_back(3);
		v2.push_back(4);
		v2.push_back(5);
		for (size_t i = 0; i < v2.size(); i++)
		{
			cout << v2[i] << " ";
		}
		cout << endl;
		vector<int>::iterator it = v2.begin();
		while (it != v2.end())
		{
			cout << *(it) << " ";
			it++;
		}
		cout << endl;
		for (auto e : v2)
		{
			cout << e << " ";
		}
		cout << endl;
		print(v2);
	}


	void test_vector3()
	{
		vector<int> v3;
		v3.push_back(1);
		v3.push_back(2);
		v3.push_back(3);
		v3.push_back(4);
		v3.push_back(5);
		for (auto e : v3)
		{
			cout << e << " ";
		}
		cout << endl;
		cout << v3.size() << endl;
		cout << v3.capacity() << endl;
		v3.resize(10,1);
		for (auto e : v3)
		{
			cout << e << " ";
		}
		cout << endl;
		cout << v3.size() << endl;
		cout << v3.capacity() << endl;
	}

	void test_vector4()
	{
		vector<int> v4;
		v4.push_back(100);
		v4.push_back(2);
		v4.push_back(30);
		v4.push_back(4);
		v4.push_back(5);
		v4.insert(v4.begin(), 10);
		for (auto e : v4)
		{
			cout << e << " ";
		}
		cout << endl;
		auto pos = find(v4.begin(), v4.end(),4);//算法
		if (pos != v4.end())
		{
			v4.insert(pos, 10);
		}
		for (auto e : v4)
		{
			cout << e << " ";
		}
		cout << endl;
		(*pos)++;
		for (auto e : v4)
		{
			cout << e << " ";
		}
		cout << endl;

		vector<int>::iterator it = v4.begin();
		while (it != v4.end())
		{
			//错误代码:不论删除还是不删除,都往后走且没有接受pos下标的位置,当删除最后一个元素时,下标未定义;
			//if (*(it) % 2 == 0)
			//{
			//	v4.erase(it);
			//}
			//++it;
			if (*(it) % 2 == 0)
			{
				it = v4.erase(it);
			}
			else
			{
				++it;
			}
		}
		for (auto e : v4)
		{
			cout << e << " ";
		}
		cout << endl;
	}
	
	//各种构造函数:
	void test_vector5()
	{
		//vector(size_t n, const T& temp=T()),使用size_t版的构造函数;
		vector<int> v1(10u, 1);
		for (auto e : v1)
		{
			cout << e << " ";
		}
		cout << endl;

		//vector(int n, const T& temp=T()),使用int版的构造函数;
		vector<int> v2(10, 1);
		for (auto e : v2)
		{
			cout << e << " ";
		}
		cout << endl;

		//vector(InputIterator first, InputIterator last);使用模板的构造函数;
		string s1("aaabbbccc");//char类型转化为整形
		vector<int> v4(s1.begin(), s1.end());
		for (auto e : v4)
		{
			cout << e << " ";
		}
		cout << endl;

		vector(InputIterator first, InputIterator last);可以使用数组,本质还是指针:
		int arr[] = { 10,20,30,40,50};//原生指针,
		vector<int> v5(arr, arr + 5);
		for (auto e : v5)
		{
			cout << e << " ";
		}
		cout << endl;


		v2.insert(v2.begin(), 10);
		v2.insert(v2.begin() + 3, 3);
		v2.insert(v2.begin(), 2);
		
		//排序:
		sort(v2.begin(), v2.end());
		for (auto e : v2)
		{
			cout << e << " ";
		}
		cout << endl;
	}

	//拷贝构造,深浅拷贝:
	void test_vector6()
	{
		//一层深拷贝
		/*vector<int> v6(10,1);
		for (auto e : v6)
		{
			cout << e << " ";
		}
		cout << endl;
		vector<int> v7(v6);
		for (auto e : v7)
		{
			cout << e << " ";
		}
		cout << endl;*/

		//两层深拷贝:
		vector<std::string> v6(3, "22222222222222222");
		for (auto e : v6)
		{
			cout << e << " ";
		}
		cout << endl;
		vector<std::string> v7(v6);
		for (auto e : v7)
		{
			cout << e << " ";
		}
		cout << endl;
	}
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值