C++ vector

Posted -A7

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++ vector相关的知识,希望对你有一定的参考价值。

vector的介绍及使用

1.1vector的介绍
1 .vector是表示可变大小数组的序列容器。
2. 就像数组一样,vector也采用的连续存储空间来存储元素。也就是意味着可以采用下标对vector的元素进行访问,和数组一样高效。但是又不像数组,它的大小是可以动态改变的,而且它的大小会被容器自动处理。
3. 本质讲,vector使用动态分配数组来存储它的元素。当新元素插入时候,这个数组需要被重新分配大小为了增加存储空间。其做法是,分配一个新的数组,然后将全部元素移到这个数组。就时间而言,这是一个相对代价高的任务,因为每当一个新的元素加入到容器的时候,vector并不会每次都重新分配大小。
4. vector分配空间策略:vector会分配一些额外的空间以适应可能的增长,因为存储空间比实际需要的存储空间更大。不同的库采用不同的策略权衡空间的使用和重新分配。但是无论如何,重新分配都应该是对数增长的间隔大小,以至于在末尾插入一个元素的时候是在常数时间的复杂度完成的。
5. 因此,vector占用了更多的存储空间,为了获得管理存储空间的能力,并且以一种有效的方式动态增长。
6. 与其它动态序列容器相比(deques, lists and forward_lists), vector在访问元素的时候更加高效,在末尾添加和删除元素相对高效。对于其它不在末尾的删除和插入操作,效率更低。比起lists和forward_lists统一的迭代器和引用更好。
1.2vector的使用
vector的文档:http://www.cplusplus.com/reference/vector/vector/.
1.2.1vector的定义

1.2.2vector的使用


1.2.3vector的空间增长问题

resize只负责开辟空间,如果确定知道需要用多少空间,reverse可以缓解vector增容的代价问题
resize开辟空间的同时还会初始化,影响size。
1.2.3vector的增删查改

1.2.4vector的迭代器失效问题
迭代器的主要作用是让算法不用关心底层的数据结构,其底层实际就是一个指针,或者是对指针进行了封装,比如,vector的迭代器就是原生态指针T*。因此迭代器失效,实际就是迭代器底层对应指针所指向的空间被销毁了,而使用一块已经被释放的空间,造成程序崩溃。
对于可能造成迭代器失效的操作有
1.会引起底层空间改变的操作都有可能造成迭代器失效,比如:resize,reverse,insert,push_back,assign等等。
2.指定元素的删除操作-earse
earse删除pos位置元素后,pos元素之后的元素会往前搬移,没有导致底层空间的改变,理论上迭代器不会失效,但是,如果pos刚好是最后一个元素,删完之后刚好是end的位置,而end位置是没有元素的,那么pos就失效了,因此删除vector上任意一个元素时,vs就认为该位置的迭代器失效了。
迭代器失效的解决方法:在使用之前,对迭代器重新赋值即可。
总结
vector的常用接口更多是插入与遍历,遍历最好用数组ret[i]的形式进行访问,因为vector里边没有对<<的重载,所以无法直接进行打印,用数组的方式会更为方便。

vector的模拟实现

namespace bit

	template<class _Ty>
	class vector
	
	public:
		typedef _Ty* iterator;
		typedef const _Ty* const_iterator;
		typedef size_t size_type;
	public:
		vector() : _start(nullptr), _finish(nullptr),_end_of_storage(nullptr)
		
		vector(int n, const _Ty& value = _Ty())
			: _start(nullptr), _finish(nullptr),
			_end_of_storage(nullptr)
		
			reserve(n);
			while(n--)
				push_back(value);
		
		vector(const_iterator first, const_iterator last)
			: _start(nullptr), _finish(nullptr),
			_end_of_storage(nullptr)
		
			reserve(last - first);
			while(first != last)
				push_back(*first++);
		
		vector(const vector<_Ty> &v)
			 : _start(nullptr), _finish(nullptr),
			_end_of_storage(nullptr)
		
			reserve(v.capacity());
			for(int i=0; i<v.size(); ++i)
				_start[i] = v[i];
			_finish = _start + v.size();
		
		vector<_Ty>& operator=(const vector<_Ty> &v)
		
			if(this != &v)
			
				vector<_Ty> tmp = v;
				swap(tmp);
			
			return *this;
		
		~vector()
		
			if(_start)
			
				delete []_start;
				_start = _finish = _end_of_storage = nullptr;
			
		
	public:
		void push_back(const _Ty &x)
		
			insert(end(), x);
		
		void pop_back()
		
			erase(end()-1);
		
		iterator begin()
		
			return _start;
		
		iterator end()
		
			return _finish;
		
	public:
		_Ty& operator[](size_t pos)
		
			return _start[pos];
		
		const _Ty& operator[](size_t pos)const 
		
			return _start[pos];
		
		const _Ty& at(size_type pos) const
		
			assert(pos>=0 && pos<size());
			return _start[pos];
		
		_Ty& at(size_type pos)
		
			assert(pos>=0 && pos<size());
			return _start[pos];
		

	public:
		iterator insert(iterator pos, const _Ty& x)
		
			if(_finish == _end_of_storage)
			
				size_t old_n = pos - _start;
				size_t new_sz = capacity()==0 ? 1 : 2*capacity();
				reserve(new_sz);
				//重新更新迭代器 pos
				pos = _start + old_n;
			

			iterator cur = end();
			while(cur != pos)
			
				*cur = *(cur-1);
				cur--;
			
			*cur = x;   //
			_finish++;
			return cur;
		

		iterator erase(iterator pos)
		
			assert(pos>=_start && pos<_finish);

			iterator cur = pos;
			while(pos < _finish)
			
				*pos = *(pos+1);
				pos++;
			
			--_finish;
			return cur;
		

		void reserve(size_type n)
		
			if(n > capacity())
			
				size_t old_sz = size();
				_Ty *new_start = new _Ty[n];
				//memcpy(new_start, _start, sizeof(_Ty)*old_sz);
				for(int i=0; i<old_sz; ++i)
				
					new_start[i] = _start[i];
				
				delete []_start;

				_start = new_start;
				_finish = _start + old_sz;
				_end_of_storage = _start + n;
			
		

		void resize(size_t n, const _Ty& value = _Ty())
		
			if(n <= size())
			
				_finish = _start + n;
				return;
			

			if(n > capacity())
			
				reserve(n);
			

			size_t offset = n - size();
			while(offset--)
			
				*_finish++ = value;
			
		

	public:
		size_t size()const
		
			return _finish - _start;
		
		size_t capacity()const
		
			return _end_of_storage - _start;
		
		bool empty()const
		
			return size() == 0;
		
	public:
		void swap(vector& str)
		
			std::swap(_start, str._start);
			std::swap(_finish, str._finish);
			std::swap(_end_of_storage, str._end_of_storage);
		
	private:
		iterator _start;
		iterator _finish;
		iterator _end_of_storage;
	;
;

以上是关于C++ vector的主要内容,如果未能解决你的问题,请参考以下文章

这些 C++ 代码片段有啥作用?

有趣的 C++ 代码片段,有啥解释吗? [复制]

以下代码片段 C++ 的说明

C++ 代码片段执行

此 Canon SDK C++ 代码片段的等效 C# 代码是啥?

C++ 代码片段(积累)