STL——vector模拟实现

  • Post author:
  • Post category:其他


vector介绍:


vector原理



vector是表示可变大小数组的序列容器。

就像数组一样,vector也采用的连续空间来存储元素。这也意味着vector也可以采用下标对元素进行访问,和数组一样高效。但是,它又不像数组一样,

它的空间是可以动态改变的,并且它的大小可以自动进行处理。

本质上来讲,vector使用动态分配的数组来存储它的元素。当新元素插入时,这个数组就需要被重新分配空间大小,为了增加存储空间。做法是:重新开辟一新的数组,然后将元素移到新的数组。

vector分配空间做法:vector会分配一些额外的空间来适应元素的增加,所以存储空间比实际需要的空间大。增长空间也是按一定的倍数进行增长。一般windows下以1.5倍进行增长,linux下以2倍进行增长。

vector模拟实现:

这里说明几个重要的实现:

vector的拷贝构造函数和赋值操作符函数(operator=),注意深浅拷贝问题,拷贝构造不好使用现代写法Swap(),赋值操作函数可以使用。

resize和reserve函数,resize要注意三种情况,小于size(),大于size()小于capacity(),大于capacity()。

reserve增容注意迭代器失效问题。

插入和删除,插入注意扩容情况,往后移动数据再插入。删除往前移动数据覆盖。

vector里元素的类型是任意的,由用户决定,所以使用模板来解决,避免因为类型不同要写多个vector类。

#pragma once

#include<iostream>
#include<Windows.h>
#include<assert.h>
using namespace std;
//使用模板
template<class T>
class vector{
public:
	typedef T * iterator;
	typedef const T* const_iterator;
	//迭代器
	iterator begin(){
		return _start;
	}
	iterator end(){
		return _finish;
	}
	const_iterator cbegin(){
		return _start;
	}
	const_iterator cend(){
		return _finish;
	}
	
	vector()
		:_start(nullptr)
		, _finish(nullptr)
		, _endofstorage(nullptr)
	{}
	vector(size_t n, const T& val = T())
		:_start(nullptr)
		, _finish(nullptr)
		, _endofstorage(nullptr)
	{
		reserve(n);
		while (_finish != (_start + n)){
			*_finish = val;
			_finish++;
		}

	}

	//不好调用Swap函数,不能调用拷贝构造函数,只能调构造函数
	vector(const vector<T>& v)
		:_start(nullptr)
		, _finish(nullptr)
		, _endofstorage(nullptr)
	{
		reserve(v.capacity());
		for (size_t i = 0; i < v.size(); i++){
			*_finish = v[i];
			_finish++;
		}

	}

	vector<int>& operator=(vector<int> v){
		Swap(v);
		return *this;

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

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

	void push_back(const T& val){
		//if (_finish == _endofstorage){
		//	size_t newcapacity = capacity() == 0 ? 2 : 2 * capacity();
		//	reserve(newcapacity);
		//}
		//*_finish = val;
		//_finish++;
		insert(_finish, val);

	}


	iterator insert(iterator pos, const T& val){
		assert(pos <= _finish);
		if (_finish == _endofstorage){
			//扩容后pos位置迭代器失效了,记录位置,重新更新pos位置
			size_t sz = pos - _start;
			size_t newcapacity = capacity() == 0 ? 2 : 2 * capacity();
			reserve(newcapacity);
			//更新pos位置
			pos = _start + sz;
		}
		
		iterator end = _finish - 1;
		while (end >= pos){
			*(end + 1) = *end;
			end--;
		}
		
		*pos = val;
		_finish++;
		return pos;
	}

	void pop_back(){
		assert(_finish != _start);
		//_finish--;

		erase(_finish - 1);
	}

	iterator erase(iterator pos){
		assert(pos < _finish);

		iterator tmp = pos;
		while (tmp < _finish){
			*tmp = *(tmp + 1);
			tmp++;
		}
		_finish--;
		return pos;
	}


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

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

	vector<T>& reserve(size_t n){
		if (n > capacity()){
			size_t oldsize = size();
			T *tmp = new T[n];
			if (_start){
				//使用赋值,调用T的赋值操作符重载函数
				for (size_t i = 0; i < size(); i++){
					tmp[i] = _start[i];
				}
				delete[] _start;
			}
			_start = tmp;
			_finish = _start + oldsize;
			_endofstorage = _start + n;
	
		}
		return *this;
	}

	void resize(size_t n, const T& val = T()){
		if (n > size()){
			if (n > capacity()){
                //如果进来没有容量
				size_t newcapacity = capacity() == 0 ? 2 : 2 * capacity();
				reserve(newcapacity);
			}
			while (_finish != (_start + n)){
				*_finish = val;
				_finish++;
			}

		}
		else{
			_finish = _start + n;
		}
		
	}

	void Swap(vector<int>& v){
		swap(_start, v._start);
		swap(_finish, v._finish);
		swap(_endofstorage, v._endofstorage);

	}


private:
	iterator _start;
	iterator _finish;
	iterator _endofstorage;
};



版权声明:本文为weixin_57023347原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。