MySTL实现之MyVector

MySTL实现

实现STL库中的基础容器及基本函数



Vector类实现

第一次自己实现模板类,一开始将定义和实现文件分开写,结果vs不能编译。后来发现模板类的实现需要和定义写在一起,因为模板中的T是在编译中才确定的,因此会找不到.cpp的实现文件。

STL中vector类模板的实现还有一个参数是内存分配器,默认是调用系统自带的分配器对内存进行分配,在本次实现中仅采用new关键字对内存进行分配。模板的类型为_T,将 _T*封装为迭代器,用于遍历 _T类型的变量。类中包装3个迭代器作为存取的指示,实现了基本的构造函数、析构函数以及常用函数。

由于有些参数传入需要使用const关键字,因此这些参数在调用其他函数时,也必须调用const关键字修饰的函数。

类中没有实现例如:

vector vec(10);
vec[0] = 0;

这种赋值形式,只能使用push_back()在vector尾部添加,或insert(it,val)在it位加入val,但每次仅能插入一个。

最后给出简单测试代码,对于一些细节的把控可能还没完善。

头文件.h

#pragma once
#ifndef _MyVector_
#define _MyVector_
#include<iostream>
template<class _T>
class MyVector {
private:
	_T* _my_first;//起始位置
	_T* _my_finish;//最后一个存入元素的后一个
	_T* _my_end;//最大容量的后一个

public:
	typedef _T* iterator;//迭代器
	//默认构造
	MyVector() :_my_first(nullptr), _my_finish(nullptr), _my_end(nullptr) {}
	/// <summary>
	/// 有参构造函数
	/// </summary>
	/// <param name="n">长度</param>
	/// <param name="val">初始值</param>
	MyVector(size_t n, const _T& val = _T()) :_my_first(nullptr), _my_finish(nullptr), _my_end(nullptr) {
		//重新申请空间
		_my_first = new _T[n];
		_my_finish = _my_first;
		_my_end = _my_first + n;
		//赋值
		for (auto it = begin(); it != _my_end; ++it) {
			*_my_finish = val;
			++_my_finish;
		}
		_my_finish = _my_first;//赋完初值后,指针归位
	}
	/// <summary>
	/// 复制构造函数
	/// </summary>
	/// <typeparam name="_T"></typeparam>
	/// <param name="v"></param>
	MyVector(const MyVector& v) {
		//得到v的容量
		size_t n = v.capacity();
		//重新申请空间
		_my_first = new _T[n];
		_my_finish = _my_first;
		_my_end = _my_first + n;
		//赋值
		//传入的v为const,对应取出的begin也要为const
		for (auto it = v.begin(); it != v.end(); ++it) {
			*_my_finish = *it;
			++_my_finish;
		}
	}
	/// <summary>
	/// 析构函数
	/// 是否应该显式调用数组中每个对象的析构函数?
	/// </summary>
	/// <typeparam name="_T"></typeparam>
	~MyVector() {
		if (_my_first) {
			delete[] _my_first;
			_my_first = _my_finish = _my_end = nullptr;
		}
	}
	//返回迭代器
	iterator begin() {
		return _my_first;
	}
	iterator end() {
		return _my_finish;
	}
	//返回常量迭代器
	iterator begin() const {
		return _my_first;
	}
	iterator end() const {
		return _my_finish;
	}
	/// <summary>
	/// 压入myvector
	/// </summary>
	/// <typeparam name="_T"></typeparam>
	/// <param name="val"></param>
	void push_back(const _T& val) {
		if (end() == _my_end) {//空间不足
			this->insert(end(), val);
		}
		else {//有空间,直接存
			this->construction(end(), val);
			_my_finish++;
		}
	}
	/// <summary>
	/// 在迭代器位置加入n个该元素,默认个数为1
	/// </summary>
	/// <param name="v"></param>
	void construction(iterator cur, const _T& val, int n = 1) {
		for (int i = 0; i < n; ++i) {
			*cur = val;
			cur++;
		}
	}
	/// <summary>
	/// 弹出myvector
	/// </summary>
	/// <typeparam name="_T"></typeparam>
	void pop_back() {
		this->erase(end());
	}
	//获取size
	size_t size() {
		return size_t(end() - begin());
	}
	size_t capacity() {
		return _my_first == nullptr ? 0 : _my_end - _my_first;
	}
	size_t capacity() const {
		return _my_first == nullptr ? 0 : _my_end - _my_first;
	}
	/// <summary>
	/// 在MyVector插入val
	/// 1、空间不足
	/// 2、直接插入
	/// </summary>
	/// <typeparam name="_T"></typeparam>
	/// <param name="pos">插入位置</param>
	/// <param name="val">插入值</param>
	void insert(iterator pos, const _T& val) {
		size_t posindex = pos - _my_first;
		if (_my_finish == _my_end){//空间不足
			size_t newcapacity = capacity() == 0 ? 2 : capacity() * 2;
			resize(newcapacity);//重新申请大小
			pos = _my_first + posindex;
		}
        //后移
		iterator end = _my_finish;
		while (end > pos){
			*end = *(end - 1);
			--end;
		}
		*pos = val;
		++_my_finish;
	}
	/// <summary>
	/// 移除pos位的元素
	/// 后面整体前移一位
	/// finish前移一位
	/// </summary>
	/// <typeparam name="_T"></typeparam>
	/// <param name="pos"></param>
	/// <returns></returns>
	iterator erase(iterator pos) {
		iterator begin = pos;
		for (iterator it = pos; it != end(); ++it) {
			*it = *(it + 1);
		}
		--_my_finish;
		return begin;
	}
	/// <summary>
	/// 重新申请空间
	/// 1.缩容			1)对象在新空间存满  2)对象在新空间只存了一部分
	/// 2.扩容
	/// </summary>
	/// <typeparam name="_T"></typeparam>
	/// <param name="n"></param>
	void resize(size_t n) {
		if (n < capacity()) {	//缩容
			_T* new_data = new _T[n];
			_T* new_fir = new_data;
			//赋值
			for (auto it = begin(); it != begin() + n && it != end(); ++it) {
				*(new_data++) = *it;
			}
			size_t old_size = size() < n ? size() : n;
			delete[] _my_first;//删除原先数据
			_my_first = new_fir;
			_my_finish = begin() + old_size;
			_my_end = begin() + n;

		}
		else if (n > capacity()) {	//扩容
			_T* new_data = new _T[n];
			_T* new_fir = new_data;
			for (auto it = begin(); it != end(); ++it) {
				*(new_data++) = *it;
			}
			size_t old_size = size();
			delete[] _my_first;//删除原先数据
			_my_first = new_fir;
			_my_finish = _my_first + old_size;
			_my_end = _my_first + n;
		}
	}
	/// <summary>
	/// 重载[]
	/// </summary>
	/// <typeparam name="_T"></typeparam>
	/// <param name="n"></param>
	/// <returns></returns>
	_T& operator[](size_t n) {
		return *(_my_first + n);
	}
	/// <summary>
	/// 重载=
	/// </summary>
	/// <typeparam name="_T"></typeparam>
	/// <param name="v"></param>
	/// <returns></returns>
	MyVector<_T>& operator=(const MyVector<_T>& v) {
		//得到v的容量
		size_t n = v.capacity();
		//重新申请空间
		_my_first = new _T[n];
		_my_finish = _my_first;
		_my_end = _my_first + n;
		//赋值
		for (auto it = v.begin(); it != v.end(); ++it) {
			*_my_finish = *it;
			++_my_finish;
		}
		return this;
	}
	bool empty() const {
		return end() == begin();
	}
};
#endif // !_MyVector_

测试代码

没有实现对于越界等问题的异常处理

#include"MyVector.h"
#include<iostream>
#include<algorithm>
int main() {
	//测试默认构造函数
	MyVector<int> vec1;
	vec1.push_back(0);
	vec1.push_back(1);
	vec1.push_back(2);
	vec1.push_back(3);
	vec1.push_back(4);
	vec1.push_back(5);
	std::cout << "vec1:" << std::endl;
	for (auto it = vec1.begin(); it != vec1.end(); ++it) {
		std::cout << *it << std::endl;
	}
	std::cout << "vec2:" << std::endl;
	//测试有参构造
	MyVector<int> vec2(5);
	for (int i = 0; i < 5; i++) {
		vec2.insert(vec2.begin(), i);
	}
	for (auto it = vec2.begin(); it != vec2.end(); ++it) {
		std::cout << *it << std::endl;
	}
	//测试赋值构造
	MyVector<int>vec3(vec2);
	std::cout << "vec3:" << std::endl;
	for (auto it = vec3.begin(); it != vec3.end(); ++it) {
		std::cout << *it << std::endl;
	}
	MyVector<int> vec4 = vec3;
	vec4.pop_back();
	vec4.pop_back();
	vec4.erase(vec4.begin() + 1);
	std::cout << "vec4:" << std::endl;
	for (auto it = vec4.begin(); it != vec4.end(); ++it) {
		std::cout << *it << std::endl;
	}
	std::cout << "vec4.size():" << vec4.size() << std::endl;
	//测试resize
	vec1.resize(3);
	std::cout << "vec1:" << std::endl;
	for (auto it = vec1.begin(); it != vec1.end(); ++it) {
		std::cout << *it << std::endl;
	}
	vec4.resize(10);
	for (int i = 2; i < 10; i++) {
		vec4.push_back(i);
	}
	std::cout << "vec4.size():" << vec4.size() << std::endl;
	vec4.insert(vec4.begin() + 5, 10);
	std::cout << "vec4.size():" << vec4.size() << std::endl;
	std::cout << "vec4:" << std::endl;
	for (auto it = vec4.begin(); it != vec4.end(); ++it) {
		std::cout << *it << std::endl;
	}
	if (vec1.empty()) {
		std::cout << "vec1为空" << std::endl;
	}
	else {
		std::cout << "vec1不空" << std::endl;
	}
	//测试能否适配算法库
	std::sort(vec4.begin(), vec4.end());
	std::cout << "vec4:" << std::endl;
	for (auto it = vec4.begin(); it != vec4.end(); ++it) {
		std::cout << *it << std::endl;
	}
	return 0;
}

总结

简单实现了一遍vector,包装了3个指针对一块连续内存空间的操作,对于更深层次的内存分配器还没有进一步实现,本次实现中仅使用new关键字对内存空间进行分配。
接下来会实现list容器及相关函数,MyVector类文件在该仓库(如果对你有帮助或者你发现了问题都可以在仓库点赞或提交问题)也可以从这里下载

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jiaoooooo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值