C++ 中的 vector 的模拟实现【代码纯享】

news2024/10/7 20:35:55

文章目录

  • C++ 中的 vector 模拟实现
    • 1. vector 的基本概念
    • 2. vector 的基本操作
    • 3. vector 的模拟实现
    • 4.代码纯享
    • 5. 总结

C++ 中的 vector 模拟实现

在 C++ 中,vector 是一个非常重要的容器,它提供了动态数组的功能。在本篇博客中,我们将尝试模拟实现一个简单的 vector 类,以便更好地理解其内部工作机制。

1. vector 的基本概念

vector 是一个封装了动态大小数组的顺序容器。与普通数组不同,vector 的大小可以根据需要动态地增加或减少,而不需要程序员手动管理内存。

2. vector 的基本操作

  • 构造函数:创建一个空的 vector 或者根据给定的初始值创建一个 vector
  • 赋值操作:将一个 vector 的内容赋值给另一个 vector
  • 访问元素:通过索引访问 vector 中的元素。
  • 插入和删除元素:在 vector 的任何位置插入或删除元素。
  • 大小操作:获取 vector 的大小或检查它是否为空。
  • 迭代器操作:提供迭代器以遍历 vector 中的元素。

3. vector 的模拟实现

首先,我们需要定义vector的基本结构。由于vector可以存储不同类型的元素,我们使用类模板来定义它:

namespace my_vector
{
	template<class T>
	class vector
	{
	public:
		// 定义迭代器类型
		typedef T* iterator;
		// 定义const迭代器类型
		typedef const T* const_iterator;

		// 其他成员变量和成员函数...
};

接下来,我们实现vector的一些基本成员函数,如默认构造函数,析构函数,拷贝构造函数:

		iterator begin()
		{
			return _start;
		}

		iterator end()
		{
			return _finish;
		}

		const_iterator begin() const
		{
			return _start;
		}

		const_iterator end() const
		{
			return _finish;
		}

		vector()
		{}

		//拷贝构造v2(v1)
		vector(const vector<T>& v)
		{
			reserve(v.capacity());
			for (auto& e : v)
			{
				push_back(e);
			}
		}

		//vector<int> v1 = { 1, 2, 3, 4, 5, 6, 7, 8 };
		//构造+拷贝构造 -> 优化 直接构造
		vector(initializer_list<T> il)
		{
			reserve(il.size());
			for (auto& e : il)
			{
				push_back(e);
			}
		}
		vector(size_t n, const T& val = T())
		{
			reserve(n);
			for (size_t i = 0; i < n; i++)
			{
				push_back(val);
			}
		}
		vector(int n, const T& val = T())
		{
			reserve(n);
			for (int i = 0; i < n; i++)
			{
				push_back(val);
			}
		}
		
		//深拷贝 v1=v3
		vector<T>& operator=(vector<T> v)
		{
			swap(v);
			return *this;
		}

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

然后,我们实现vector的迭代器。迭代器是一种行为类似于指针的对象,它能够遍历容器中的元素:

		bool empty()
		{
			return _start == _finish;
		}

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

			if (_finish == _endofstorage)
			{
				size_t len = pos - _start;
				reserve(capacity() == 0 ? 4 : capacity() * 2);

				//如果扩容了要更新pos
				pos = _start + len;
			}
			
			iterator it = _finish - 1;
			while (it >= pos)
			{
				*(it + 1) = *it;
				it--;
			}
			*pos = val;
			_finish++;
		}

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

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

			return pos;
		}

最后,我们实现vector的一些基本操作,如push_back、pop_back、begin、end等:

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

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

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

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

		void reserve(size_t n)
		{
			if (n > capacity())
			{
				T* tmp = new T[n];
				size_t old_size = size();
				//memcpy(tmp, _start, size()*sizeof(T));
				for (size_t i = 0; i < old_size; i++)
				{
					tmp[i] = _start[i];
				}
				delete[] _start;

				_start = tmp;
				_finish = tmp + old_size;
				_endofstorage = tmp + n;
			}
		}

		void resize(size_t n,const T& val=T())
		{
			if (n > size())
			{
				reserve(n);
				//插入
				while (_finish<_start + n)
				{
					*_finish = val;
					_finish++;
				}
			}
			else
			{
				//删除
				_finish = _start + n;
			}
		}

		void push_back(const T& val)
		{
			/*if (_finish == _endofstorage)
			{
				reserve(capacity() == 0 ? 4 : capacity() * 2);
			}

			*_finsh = val;
			_finsh++;*/
			insert(end(), val);
		}

		void pop_back()
		{
			/*assert(empty());

			_finsh--;*/

			erase(--end());
		}

4.代码纯享

#pragma once
#include <assert.h>

namespace my_vector
{
	template<class T>
	class vector
	{
	public:
		// 定义迭代器类型
		typedef T* iterator;
		// 定义const迭代器类型
		typedef const T* const_iterator;

		// 其他成员变量和成员函数...
		iterator begin()
		{
			return _start;
		}

		iterator end()
		{
			return _finish;
		}

		const_iterator begin() const
		{
			return _start;
		}

		const_iterator end() const
		{
			return _finish;
		}

		vector()
		{}

		//拷贝构造v2(v1)
		vector(const vector<T>& v)
		{
			reserve(v.capacity());
			for (auto& e : v)
			{
				push_back(e);
			}
		}

		//vector<int> v1 = { 1, 2, 3, 4, 5, 6, 7, 8 };
		//构造+拷贝构造 -> 优化 直接构造
		vector(initializer_list<T> il)
		{
			reserve(il.size());
			for (auto& e : il)
			{
				push_back(e);
			}
		}

		//类模板的成员函数可以是函数模板
		template <class InputIerator>
		vector(InputIerator first, InputIerator last)
		{
			while (first != last)
			{
				push_back(*first);
				first++;
			}
		}

		vector(size_t n, const T& val = T())
		{
			reserve(n);
			for (size_t i = 0; i < n; i++)
			{
				push_back(val);
			}
		}

		vector(int n, const T& val = T())
		{
			reserve(n);
			for (int i = 0; i < n; i++)
			{
				push_back(val);
			}
		}

		void swap(vector<T>& v)
		{
			std::swap(_start, v._start);
			std::swap(_finsh, v._finsh);
			std::swap(_endofstorage, v._endofstorage);
		}

		//深拷贝 v1=v3
		vector<T>& operator=(vector<T> v)
		{
			swap(v);
			return *this;
		}

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

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

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

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

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

		void reserve(size_t n)
		{
			if (n > capacity())
			{
				T* tmp = new T[n];
				size_t old_size = size();
				//memcpy(tmp, _start, size()*sizeof(T));
				for (size_t i = 0; i < old_size; i++)
				{
					tmp[i] = _start[i];
				}
				delete[] _start;

				_start = tmp;
				_finish = tmp + old_size;
				_endofstorage = tmp + n;
			}
		}

		void resize(size_t n,const T& val=T())
		{
			if (n > size())
			{
				reserve(n);
				//插入
				while (_finish<_start + n)
				{
					*_finish = val;
					_finish++;
				}
			}
			else
			{
				//删除
				_finish = _start + n;
			}
		}

		void push_back(const T& val)
		{
			/*if (_finish == _endofstorage)
			{
				reserve(capacity() == 0 ? 4 : capacity() * 2);
			}

			*_finsh = val;
			_finsh++;*/
			insert(end(), val);
		}

		void pop_back()
		{
			/*assert(empty());

			_finsh--;*/

			erase(--end());
		}

		bool empty()
		{
			return _start == _finish;
		}

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

			if (_finish == _endofstorage)
			{
				size_t len = pos - _start;
				reserve(capacity() == 0 ? 4 : capacity() * 2);

				//如果扩容了要更新pos
				pos = _start + len;
			}
			
			iterator it = _finish - 1;
			while (it >= pos)
			{
				*(it + 1) = *it;
				it--;
			}
			*pos = val;
			_finish++;
		}

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

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

			return pos;
		}

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

	//函数模板
	//template <typename T>
	template <class T>
	void print_vector(const vector<T>& v)
	{
		for (size_t i = 0; i < v.size(); i++)
		{
			cout << v[i] << " ";
		}
		cout << endl;

		//typename vector<int>::const_iterator it = v.begin();
	//	auto it = v.begin();
	//	while (it != v.end())
	//	{
	//		cout << *it << " ";
	//		it++;
	//	}
	//	cout << endl;

	//	for (auto e : v)
	//	{
	//		cout << e << " ";
	//	}
	//	cout << endl;
	}

	void test_vector1()
	{
		vector<int> v1;
		v1.push_back(1);
		v1.push_back(2);
		v1.push_back(3);
		v1.push_back(4);
		v1.push_back(5);
		v1.push_back(6);

		print_vector(v1);

		v1.insert(v1.begin(),3);
		v1.insert(v1.begin() + 2, 3);
		v1.insert(v1.begin() + 4, 3);
		v1.insert(v1.begin() + 6, 3);

		print_vector(v1);

		v1.erase(v1.begin()+4);

		print_vector(v1);

		vector<double> v2;
		v2.push_back(0.1);
		v2.push_back(0.2);
		v2.push_back(0.3);
		v2.push_back(0.4);
		v2.push_back(0.5);
		v2.push_back(0.6);
		print_vector(v2);

	}

	void test_vector2()
	{
		vector<int> v1;
		v1.push_back(1);
		v1.push_back(2);
		v1.push_back(3);
		v1.push_back(4);
		v1.push_back(5);
		v1.push_back(6);

		print_vector(v1);

		v1.resize(10);

		print_vector(v1);

		v1.resize(3);

		print_vector(v1);
	}

	void test_vector3()
	{
		vector<int> v3(10,1);
		print_vector(v3);

	}

	void test_vector4()
	{
		auto x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
		cout << typeid(x).name() << endl;
		cout << sizeof(x) << endl;

		initializer_list<int> y = { 1, 2, 3, 4, 5, 6, 7 };

		//单参数的构造函数,隐式类型转换
		string str = "111111";//构造+拷贝构造->优化 直接构造
		const string& str1 = "111111";//构造+拷贝构造->优化 直接构造
		vector<string> v;
		v.push_back(str);
		v.push_back(string("22222"));
		v.push_back("33333");

		int i = 1;
		//不推荐 --- C++11
		int j = { 1 };
		int k{ 1 };

		//跟上面类似
		//隐式转化+优化
		vector<int> v1 = { 1, 2, 3, 4, 5, 6, 7, 8 };
		for (auto e : v1)
		{
			cout << e << " ";
		}
		cout << endl;

		//直接构造
		vector<int> v2({ 1, 2, 3, 10, 20, 30 });
		for (auto e : v2)
		{
			cout << e << " ";
		}
		cout << endl;
	}

	void test_vector5()
	{
		vector<string> v;
		v.push_back("11111");
		v.push_back("11111");
		v.push_back("11111");
		v.push_back("11111");
		v.push_back("11111");
		v.push_back("11111");

		for (auto& e : v)
		{
			cout << e << " ";
		}
		cout << endl;
	}

	void test_vector6()
	{
		vector<int> v1;
		v1.push_back(1);
		v1.push_back(1);
		v1.push_back(1);
		v1.push_back(1);
		v1.push_back(1);
		v1.push_back(1);

		print_vector(v1);

		vector<int>::iterator it = v1.begin() + 3;
		v1.insert(it, 40);

		print_vector(v1);
	}
}

5. 总结

通过这个简单的 vector 模拟实现,我们不仅加深了对 vector 容器的理解,还学习了如何在 C++ 中实现一个动态数组。当然,实际的 vector 类还包含更多的功能和优化,我这个只是进行了简单的实现

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1566008.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

搭建电商网站外贸网站用API接口可以实现哪些功能(天猫API接口|京东API接口)

在电商领域&#xff0c;API接口可以实现多种功能&#xff0c;起到连接内外部系统及优化电商业务流程等多种作用&#xff0c;从而来提高电商企业的运营效率。 具体来看&#xff0c;API接口接入可以用来&#xff1a; 商品管理&#xff1a; API接口能够用来获取商品详情等&#…

OR- M406A固态继电器SSR光耦,对标替代TLP170A/ASSR-1218等

低工作电流 低导通电阻 高隔离电压 400V , 600V 输出耐受电压 工业温度范围&#xff1a;-40 to 85℃ 特征 高输入输出隔离电压 &#xff08; Viso 3&#xff0c;750Vrms &#xff09; 采用 400V 和 600V 负载电压系列 常开信号极点信号投射继电器 低工作电流 低…

Redis安装-Docker

安装redis的docker容器 1、创建redis挂载目录 mkdir -p /liuchaoxu/redis/{data,conf}2、复制配置文件 在 /liuchaoxu/redis/conf 目录中创建文件 redis.conf&#xff0c;文件从 redis-6.2.7.tar.gz 中解压获取 修改默认配置(从上至下依次)&#xff1a; #bind 127.0.0.1 …

小明的背包-dp_python

用户登录 动态规划的思想是自底向上&#xff0c;先求局部最优解然后求全局最优解。 dp[i][j]代表的是当前状态物品的数量以及背包的容量。 N, V map(int,input().split()) dp [[0 for _ in range(V1)] for _ in range(N1)]for i in range(1,N1):v, w map(int,input().split(…

CSS样式-字体类型,文本对齐,外观修饰,文本缩进,文本行间距,外部引用css样式

字体类型和字体属性调整 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Css字体类型大小</title&…

浅述安防视频监控平台EasyCVR视频汇聚管理系统运维管理能力

智慧安防监控EasyCVR视频管理平台能在复杂的网络环境中&#xff0c;将前端设备统一集中接入与汇聚管理。国标GB28181协议视频监控/视频汇聚EasyCVR平台可以提供实时远程视频监控、视频录像、录像回放与存储、告警、语音对讲、云台控制、平台级联、磁盘阵列存储、视频集中存储、…

如何保证Redis的缓存和数据库中的数据的一致性?

Redis的缓存如何和数据库中的数据保持一致性&#xff1f; 我们都知道&#xff0c;Redis是一个基于内存的键值存储系统&#xff0c;数据完全存放在内存中&#xff0c;这使得它的读写速度远超传统的硬盘存储数据库。对于高访问频率、低修改率的数据&#xff0c;通过将它们缓存在…

4.6 offset指令,jmp short指令,far,dword ptr各种跳转指令

4.6 offset指令&#xff0c;jmp short指令&#xff0c;far&#xff0c;dword ptr各种跳转指令 可以修改IP&#xff0c;或同时修改CS和IP的指令统称为转移指令。概括的讲&#xff0c;转移指令就是可以控制CPU执行内存中某处代码的指令 1. 转移指令 1.1 8086CPU的转移行为有以…

城市治理/县域治理方案:构建基于AI视频能力的“一张网”,助力新型城市发展

TSINGSEE青犀AI算法中台是一款平台型产品&#xff0c;专注于提供各行业中小场景部署解决方案。平台具备接入广、性能强、支持跨平台、芯片国产化等特点&#xff0c;可提供丰富的视图接入能力和智能分析能力。 平台采用了多项IT高新技术&#xff0c;包括视频编解码技术、嵌入式…

宁盾身份域管与Coremail邮件系统完成兼容互认证,持续深化信创布局

在信创国产化改造的背景下&#xff0c;企业邮箱的替换是许多党政、央国企、金融、制造企业面临的重要任务。为了满足企业对国产邮箱、OA等其他应用、终端实现统一身份认证&#xff0c;宁盾国产化身份域管与 Coremail XT 安全增强电子邮件系统 V5.0、V6.0 完成了产品兼容互认证&…

从redux的基本概念渐进式理解redux/toolkit的用法

概念 Redux toolkit是帮助提高redux开发效率的一个库 React-redux 是将React和Redux toolkit绑定在一起的一个库 action 是一个对象,里面有一个type属性 action creator是一个函数,这个函数可以返回上面的action对象。 reducer 是一个函数,接受两个参数(initilastate, acti…

【Vue3源码学习】— CH2.8 Vue 3 响应式系统小结

Vue 3 响应式系统小结 1.核心概念1.1 Proxy和Reflect1.2 响应式API1.3 依赖收集与更新触发1.4 触发更新&#xff08;Triggering Updates&#xff09;&#xff1a;1.5 副作用函数&#xff08;Effect&#xff09;1.6 计算属性和观察者1.7 EffectScope1.8 性能优化&#xff1a; 2.…

基于深度学习的机场航拍小目标检测系统(网页版+YOLOv8/v7/v6/v5代码+训练数据集)

摘要&#xff1a;在本博客中介绍了基于YOLOv8/v7/v6/v5的机场航拍小目标检测系统。该系统的核心技术是采用YOLOv8&#xff0c;并整合了YOLOv7、YOLOv6、YOLOv5算法&#xff0c;从而进行性能指标的综合对比。我们详细介绍了国内外在机场航拍小目标检测领域的研究现状、数据集处理…

多类别分类器(Machine Learning研习十八)

多类别分类器 二元分类器可以区分两个类别&#xff0c;而多类别分类器&#xff08;也称为多叉分类器&#xff09;可以区分两个以上的类别。 一些 Scikit-Learn 分类器&#xff08;如 LogisticRegression、RandomForestClassifier 和 GaussianNB&#xff09;能够原生处理多个类…

硬件了解 笔记 2

CPU 内存控制器&#xff1a;负责读写数据 代理系统和平台IO&#xff1a;与主板上的芯片组通信&#xff0c;并管理PC中其他组件之间的数据流 主板&#xff1a;巨大的印刷电路板 Chipset&#xff1a;芯片组&#xff0c;位于散热器下方&#xff0c;直接连接到CPU的系统代理部分 …

HTTP/1.1、HTTP/2、HTTP/3 演变(计算机网络)

HTTP/1.1 相比 HTTP/1.0 提高了什么性能&#xff1f; HTTP/1.1 相比 HTTP/1.0 性能上的改进&#xff1a; 使用长连接改善了短连接造成的性能开销。支持管道网络传输&#xff0c;只要第一个请求发出去了&#xff0c;不必等其回来&#xff0c;就可以发第二个请求出去&#xff0c…

UniApp 应用发布到苹果商店指南

&#x1f680; 想要让你的 UniApp 应用在苹果商店亮相吗&#xff1f;别着急&#xff0c;让我来带你一步步完成这个重要的任务吧&#xff01;在这篇博客中&#xff0c;我将详细介绍如何将 UniApp 应用顺利发布到苹果商店&#xff0c;让你的应用跻身于苹果生态之中。 引言 &…

MySQL 数据学习笔记速查表(视图、存储过程、事务)

文章目录 十三、视图1、视图是什么&#xff1f;2、视图的特性&#xff1f;3、视图的作用&#xff1f;4、视图的用途&#xff1f;5、视图的使用&#xff1f;1、基本语法2、创建视图3、调用视图4、视图练习(1) 利用试图简化复杂的联结(2) 利用视图重新格式化检索出的数据(3) 利用…

【flutter封装图片/视频选择控件】

引入库 wechat_assets_picker: ^6.0.5 、video_player: ^2.5.1 # 视频播放、 flutter_screenutil: ^5.7.0 import dart:async; import dart:io; import package:generated/l10n.dart; import package:jade/configs/PathConfig.dart; import package:jade/customWidget/addImag…

gateway应用(1)

1 简介 简单理解---业务服务的统一入口&#xff0c;方便实现&#xff0c;服务路由&#xff0c;安全&#xff0c;限流&#xff0c;过滤&#xff0c;黑白名单&#xff0c;证书加密解密&#xff0c;服务降级/熔断&#xff0c;灰度&#xff0c;等等 2 介绍 Predicate&#xff08…