c++简单实现-vector

模拟实现一个STL容器-vector

vector文档:
         1、 vector是表示可变大小数组的序列容器, 采用连续存储空间来储存元素(像数组一样) 支持下标访问和修改, 但是又与数组不同, 它的长度是可以动态改变的,而且它的大小会被容器自 动处理。
         2、 对于插入元素需要重新分配空间增加存储空间,它的作法不是很高效, 先开辟一块更大的空间, 然后把数据拷过来, 这是一个费时的操作, 不高效!
         3、 :vector会分配一些额外的空间以适应可能的增长,因为存储空间比实际需要的存 储空间更大。不同的库采用不同的策略权衡空间的使用和重新分配。 本次模拟实现的vector是以2倍的方式分配的!
         4、 与其它动态序列容器相比(deques, lists and forward_lists), vector在访问元素的时候更加高效,在 末尾添加和删除元素相对高效。对于其它不在末尾的删除和插入操作,效率更低。比起lists和 forward_lists统一的迭代器和引用更好。

#include<iostream>
#include<assert.h>

using namespace std;

//vetcor的实现是采用类模板实现的。
template<class T>
class Vector {
public:
	typedef T* iterator;
	typedef const T* const_iterator;

	Vector()
		:_start(nullptr)
		, _finsh(nullptr)
		, _eos(nullptr)
	{
		//Vector函数地构造函数
	}
	
	void Pushback(const T& val) {
		if (_finsh == _eos) {
			size_t newC = _start == nullptr ? 1 : 2 * Capacity();
			Reserve(newC);
		}
		
		*_finsh = val;
		++_finsh;
	}

	//Reserve是一个重新设置容量大小的函数, 只增不减! 
	void Reserve(size_t newC) {
		int sz = Size();

		if (newC > Capacity()) {

			T* tmp = new T[newC];

			for (int i = 0; i < sz; ++i) {
				tmp[i] = _start[i];
			}

			delete[] _start;

			_start = tmp;
			_finsh = _start + sz;
			_eos = _start + newC;
		}
	}
	
	T& operator[](size_t pos) {
		if (pos < Size()) {
			return _start[pos];		
		}
		
	}

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

	iterator begin() {
		return _start;
	}

	iterator end() {
		return _finsh;
	}

	const_iterator begin()  const {
		return _start;
	}

	const_iterator end() const {
		return _finsh;
	}

	void Insert(iterator pos, const T& val) {
		//增容会是迭代器失效, 因此重新开辟空间会存在空间迁移, 这样之前迭代器指向的地方就可能丢失!
		
		//我必须要加上断言!
		assert(pos >= begin() && pos <= end());

		int len = pos - _start;

		if (_finsh == _eos) {
			size_t newC = _start == nullptr ? 1 : 2 * Capacity();
			Reserve(newC);
		}

		//更新pos迭代器位置 - 可能重新开辟的空间会导致迭代器失效, 以你需要更新迭代器pos!
		pos = _start + len;

		for (iterator i = _finsh; i > pos; --i) {
			*i = *(i - 1);
		}

		*pos = val;
		++_finsh;
	}

	//任意位置删除函数
	iterator Earse(iterator pos) {
		
		assert(pos >= begin() && pos <= end());
		
		for (iterator i = pos; i < end() - 1; ++i) {
			(*i) = *(i + 1);
		}

		--_finsh;
		return pos;
	}

	//拷贝构造函数 - 是重新开辟的, 这是完全新的!
	Vector(const Vector<T>& vec)
		:_start(new T[vec.Capacity()])
		, _finsh(_start + vec.Size())
		, _eos(_start + vec.Capacity())
	{
		//数据拷贝过来!
		for (int i = 0; i < vec.Size(); ++i) {
			_start[i] = vec._start[i];
		}
	}

	template<class Inputiterator>
	Vector(Inputiterator first, Inputiterator end) {
		while (first != end) {
			Pushback(*first);
			++first;
		}
	}

	////赋值拷贝函数
	//Vector<T>& operator=(const Vector<T>& vec)
	//{
	//	if (_start) {
	//		//如果开辟好了, 则删除
	//		delete[] _start;
	//	}

	//	_start = new T[vec.Capacity()];
	//	_finsh = _start + vec.Size();
	//	_eos = _start + vec.Capacity();
	//	
	//for (int i = 0; i < vec.size(); ++i) {
	//	_start[i] = vec._start[i];
	//}

	//	return *this;
	//}

	//现代写法
	Vector<T>& operator=(Vector<T> vec)
	{
		Swap(vec);
		return *this;
	}

	void Swap(Vector<T>& vec) {
		swap(_start, vec._start);
		swap(_finsh, vec._finsh);
		swap(_eos, vec._eos);
	}

	~Vector() {
		if (_start) {
			//vector是顺序开辟的, 因此这样删除是可以的!
			delete[] _start;
			_start = _finsh = _eos = nullptr;
		}
	}

	size_t Size() const {
		return _finsh - _start;
	}

	size_t Capacity() const {
		return _eos - _start;
	}

private:
	//我们设置3个指针来这样做, 这样更加方便地完成任务!
	iterator _start;
	iterator _finsh;
	iterator _eos;
};

能力有限, 仅实现部分接口, 望大佬们多多包涵!

发布了25 篇原创文章 · 获赞 16 · 访问量 923

猜你喜欢

转载自blog.csdn.net/weixin_44024891/article/details/104121880