C++实现vector容器

Posted Wecccccccc

tags:

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

代码如下:

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

template<typename T>
class Vector
{
public:
	typedef T* iterator;
	typedef const T* const_iterator;

	Vector() :_start(nullptr), _finish(nullptr), _endOfStorage(nullptr) {};

	Vector(int n, const T &val = T()) :_start(new T[n]), _finish(_start + n), _endOfStorage(_finish)
	{
		for (int i = 0; i < n; i++)
		{
			_start[i] = val;
		}
	}



	/*使用新的迭代器的原因是使传入的迭代器可以是任意类型的,
	如果使用Vector的迭代器,那么传入的迭代器的类型只能和Vector的类型一样,
	这里拿string举例,创建一个char类型的Vector,
	但是传入的迭代器并不是char类型的,
	可以是字符数组的迭代器或者是string的迭代器。
	只要通过解引用是char类型就可以
	例如:
	string str = "Hello Wecccccccc";
	Vector<char> v4(str.begin(), str.end());
	*/
	template<typename InputIterator>
	Vector(InputIterator first, InputIterator last) :_start(nullptr), _finish(nullptr), _endOfStorage(nullptr)
	{
		while (first != last)
		{
			push_back(*first);
			++first;
		}
	}

	~Vector()
	{
		if (_start)
		{
			delete[] _start;
			_start = _finish = _endOfStorage = nullptr;
		}
	}

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

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

	void push_back(const T&val)
	{
		if (_finish == _endOfStorage)
		{
			size_t newC = _endOfStorage == nullptr ? 1 : 2 * capacity();
			reserve(newC);
		}

		*_finish = val;
		++_finish;
	}

	//通过memcpy内存拷贝(浅拷贝),会造成二次释放内存的情况,不安全,会报异常。
	/*void reserve(size_t n)
	{
		if (n > capacity())
		{
			size_t sz = size();
			T *tmp = new T[n];

			if (_start != nullptr)
			{
				memcpy(tmp, _start, sizeof(T) * size());
				delete[] _start;
			}

			_start = tmp;
			_finish = _start + sz;
			_endOfStorage = _start + n;
		}
	}*/

	//深拷贝
	void reserve(size_t n)
	{
		if (n > capacity())
		{
			size_t sz = size();
			T *tmp = new T[n];

			if (_start != nullptr)
			{
				for (size_t i = 0; i < sz; i++)
				{
					tmp[i] = _start[i];
				}
				delete[]_start;
			}

			_start = tmp;
			_finish = _start + sz;
			_endOfStorage = _start + n;
		}
	}

	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];
	}

	void resize(size_t n, const T&val = T())
	{
		if (n > capacity())
		{
			reserve(n);
		}

		if (n > size())
		{
			while (_finish != _start + n)
			{
				*_finish = val;
				++_finish;
			}
		}

		_finish = _start + n;
	}

	void insert(iterator pos, const T &val)
	{
		assert(pos >= _start || pos < _finish);

		if (_finish == _endOfStorage)
		{
			size_t offset = pos - _start;
			size_t newC = _endOfStorage == nullptr ? 1 : 2 * capacity();
			reserve(newC);

			pos = _start + offset;
		}

		iterator end = _finish;
		while (end != pos)
		{
			*end = *(end - 1);
			--end;
		}
		*pos = val;
		++_finish;
	}

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

		iterator start = pos + 1;

		while (start != _finish)
		{
			*(start - 1) = *start;
			++start;
		}
		--_finish;

		return pos + 1; //返回值:指向删除元素的下一个元素。
	}

	void pop_back()
	{
		if (size() > 0) erase(end() - 1);
	}



private:
	iterator _start;
	iterator _finish;
	iterator _endOfStorage;
};

template<typename T>
void PrintVector(Vector<T> &vec)
{
	typename Vector<T>::iterator it = vec.begin();
	while (it != vec.end())
	{
		cout << *it;
		++it;
	}
	cout << endl;
}

template<typename T>
void PrintVectorFor(Vector<T> &vec)
{
	for (auto &e : vec)
	{
		cout << e;
	}
	cout << endl;
}

测试代码如下:

#include <iostream>
#include <algorithm>
#include "Vector.h"
using namespace std;

int main()
{
	Vector<int>v1;
	Vector<int>v2(3,5);
	Vector<char>v3(5);
	cout << v1.size() << endl;
	cout << v1.capacity() << endl;
	cout << v2.size() << endl;
	cout << v2.capacity() << endl;
	cout << v3.size() << endl;
	cout << v3.capacity() << endl;
	string str = "Hello Wecccccccc";
	Vector<char> v4(str.begin(), str.end());
	v4.push_back('1');
	v4.push_back('2');
	v4.push_back('3');
	v4.reserve(100);
	cout << v4.size() << endl;
	cout << v4.capacity() << endl;
	PrintVector(v4);
	PrintVectorFor(v4);

	v4.resize(3);
	PrintVector(v4);
	v4.resize(4, '4');
	PrintVector(v4);

	Vector<int>v5;
	v5.push_back(2);
	v5.push_back(3);
	v5.push_back(5);
	v5.push_back(6);
	v5.insert(v5.begin(), 1);
	PrintVector(v5);
	v5.insert(v5.begin() + 3, 4);
	PrintVector(v5);
	v5.insert(v5.end(), 7);
	PrintVector(v5);
	v5.erase(v5.begin());
	PrintVector(v5);
	v5.erase(v5.end() - 1);
	PrintVector(v5);
	v5.pop_back();
	PrintVector(v5);
	Vector<int>::iterator it = find(v5.begin(), v5.end(), 5);
	if (it != v5.end())
	{
		cout << *it << endl;
	}
	else cout << "not find" << endl;

	it = find(v5.begin(), v5.end(), 1);
	if (it != v5.end())
	{
		cout << *it << endl;
	}
	else cout << "not find" << endl;
	return 0;
}

测试结果:
在这里插入图片描述

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

c++——STL容器之vector的使用和模拟实现

C++中vector容器

c++ vector容器 插入元素时实现自动排序

C++中vector的用法

C++ vector类型要点总结(以及各种algorithm算法函数)

C++初阶第十篇——vector(vector常见接口的用法与介绍+vector的模拟实现)