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

文章目录

  • 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=v3vector<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);//如果扩容了要更新pospos = _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=v3vector<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);//如果扩容了要更新pospos = _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++11int 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.mzph.cn/news/789833.shtml

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

相关文章

函数参数缺省和内联函数【C++】

文章目录 函数参数缺省函数参数缺省的条件和要求 内联函数内联函数的工作原理内联函数的定义方法内联函数的要求解决方法&#xff1a;直接在.h中定义内联函数的函数体 内联函数再Debug模式下默认是不展开的 函数参数缺省 顾名思义&#xff1a;可以少传一个/多个参数给函数&…

防止推特Twitter账号被冻结,应该选什么代理类型IP?

在处理多个 Twitter 帐号时&#xff0c;选择合适的代理IP对于避免大规模帐户暂停至关重要。现在&#xff0c;问题出现了&#xff1a;哪种类型的代理是满足您需求的最佳选择&#xff1f;下面文章将为你具体讲解推特账号冻结原因以及重点介绍如何选择代理IP。 一、推特账号被冻结…

3个 JavaScript 字符串截取方法

在 JavaScript 中&#xff0c;可以使用 substr()、slice() 和 substring() 方法截取字符串. substring() substring() 方法返回一个字符串在开始索引到结束索引之间的一个子集&#xff0c;或从开始索引直到字符串的末尾的一个子集。语法如下&#xff1a; str.substring(inde…

通信术语:初学者入门指南(二)

1.SAR&#xff1a;Synthetic Aperture Radar合成孔径雷达&#xff0c;是一种雷达系统&#xff0c;通常用于地球或行星的遥感成像。相较于传统的实孔径雷达&#xff0c;SAR 通过在相对较长的时间内&#xff0c;对来自同一地点的多个雷达反射信号进行综合处理&#xff0c;实现了更…

【C+ +】第一个C+ + 项目的创建及namespace命名空间解释C++中的输入输出

目录 1.创建第一个c项目 1.1项目创建 1.2 .cpp源文件建立 1.3 第一个c程序hello world对比c语言hello world 2.命名空间 2.1 C关键字 2.2 命名空间---解决c语言中的命名冲突 2.2.1 namespace命名空间用法 2.2.2 &#xff1a;&#xff1a; 预作用限定符 2.2.3 命名空间的嵌套…

【嵌入式智能产品开发实战】(七)—— 政安晨:通过ARM-Linux掌握基本技能【环境准备:树莓派】

目录 Raspberry Pi OS 下载系统镜像 使用SSH客户端登陆 升级更新 政安晨的个人主页&#xff1a;政安晨 欢迎 &#x1f44d;点赞✍评论⭐收藏 收录专栏: 嵌入式智能产品开发实战 希望政安晨的博客能够对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正…

人工智能|深度学习——基于Xception实现戴口罩人脸表情识别

一、项目背景 近年来&#xff0c;随着人工智能技术的不断发展&#xff0c;人脸表情识别已经成为了计算机视觉领域中的重要研究方向之一。然而&#xff0c;在当前的疫情形势下&#xff0c;佩戴口罩已经成为了一项必要的防疫措施&#xff0c;但是佩戴口罩会遮挡住人脸的部分区域&…

换到idf 5.0版本后报错 jsmn could not be found

原因&#xff1a; idf5.0去掉了部分组件&#xff0c;包括jsmn&#xff0c;工程中adf又用到了这个组件&#xff0c;所以会报错。 解决办法&#xff1a; 升级adf到新版本即可。

docker导出导入镜像

docker导出镜像 查看要导出的镜像 docker images主要有两列 REPOSITORY TAG 导出命令 导出公式 docker save -o xxxx.tar REPOSITORY:TAG例子 docker save -o minio.tar minio/minio:latestminio/minio:latest可以使用image id代替&#xff0c;但是使用image id会导致导…

能效监测终端为什么这么好用?

能效监测终端是一种现代管理工具&#xff0c;它在企业和机构的能源管理体系中起着核心的作用。这些监测设备能够精确掌握用电设备的功耗情况&#xff0c;为用户实现节能减排和成本控制提供了有效的技术支持。以下内容将具体解释为什么能效监测终端如此好用&#xff0c;并从多个…

风声 | “革命”启动,这里是量子的新起点——

非洲正站在量子技术变革的前沿。 尽管非洲的量子安全技术尚未达到其他地区的先进水平&#xff0c;但它被视为未来计算技术发展的关键要素。如《福布斯非洲》所述&#xff1a;“量子计算目前的发展阶段&#xff0c;可以比喻为20世纪60年代的传统计算技术水平。” 非洲拥有众多的…

收下这份地表最强参会指南,4月16日,玩转百度Create大会不迷路

欢迎来到英杰社区&#xff1a; https://bbs.csdn.net/topics/617804998 欢迎来到阿Q社区&#xff1a; https://bbs.csdn.net/topics/617897397 &#x1f4d5;作者简介&#xff1a;热爱跑步的恒川&#xff0c;致力于C/C、Java、Python等多编程语言&#xff0c;热爱跑步&#xff…

vulnhub之devguru靶场提权过程(vulnhub打靶日记)

一、环境搭建 VM版本&#xff1a;17.5.1 build-23298084 攻击机&#xff1a;Kali2024&#xff08;下载地址&#xff1a;https://www.kali.org/&#xff09; 靶机&#xff1a;vulnhub靶场Devguru&#xff08;下载地址&#xff1a;https://www.vulnhub.com/entry/devguru-1,62…

C++——异常机制

目录 一&#xff0c;背景 1.1 C语言处理错误的方式 1.2 C异常概念 二&#xff0c;异常的使用 2.1 异常的简单使用 2.2 异常的匹配原则 2.3 异常抛对象 2.4 异常的重新抛出 2.5 异常安全 三&#xff0c;自定义异常体系 四&#xff0c;异常优缺点 4.1 优点 4.2 缺点 …

【爬虫框架Scrapy】02 Scrapy入门案例

接下来介绍一个简单的项目&#xff0c;完成一遍 Scrapy 抓取流程。通过这个过程&#xff0c;我们可以对 Scrapy 的基本用法和原理有大体了解。 1. 本节目标 本节要完成的任务如下。 创建一个 Scrapy 项目。 创建一个 Spider 来抓取站点和处理数据。 通过命令行将抓取的内容…

从零开始为香橙派orangepi zero 3移植主线linux——2.linux kernel

从零开始为香橙派orangepi zero 3移植主线linux——2.linux kernel 0.环境搭建补档NFS服务TFTP服务 一、linux kernel编译二、运行 0.环境搭建补档 linux kernel验证时&#xff0c;使用tftp服务从ubuntu主机下载启动更加方便&#xff0c;等到验证无误后再一次性烧写到tf卡。所以…

基于java+SpringBoot+Vue的校园交友网站设计与实现

基于javaSpringBootVue的校园交友网站设计与实现 开发语言: Java 数据库: MySQL技术: SpringBoot MyBatis工具: IDEA/Eclipse、Navicat、Maven 系统展示 前台展示 后台展示 系统简介 整体功能包含&#xff1a; 校园交友网站是一个为在校师生提供一个交流互动、寻找朋友的…

vue3+ts 调用接口,数据显示

数据展示 &#xff08;例&#xff1a;展示医院等级数据&#xff0c;展示医院区域数据同理。&#xff09; 接口文档中&#xff0c;输入参数 测试一下接口&#xff0c;发请求 看是否能够拿到信息 获取接口&#xff0c;api/index.ts 中 /home/index.ts // 统一管理首页模块接口 i…

ansible-自动化工具

一、ansible概述 不是C/S架构&#xff0c;就是一种工具 1&#xff1a;linux自动化运维 编写程序实现运维自动化&#xff1a;shell python 工具模式自动化&#xff1a; ①OS Provisioning&#xff1a; RedHat satellite&#xff1b;PXE&#xff08;可实现dhcp和tftp&#…

PFC交流电压跌落测试实现方法与仿真

目录 前言 交流电压跌落测试 仿真验证 总结 前言 之前双向交错的图腾柱仿真到代码生成系统验证已经实现&#xff0c;最近在学习如何解决交流电压跌落的问题&#xff0c;目前根据需要通过仿真实现了该工况的模拟&#xff0c;这里简单记录一下。 双向交错CCM图腾柱无桥单相PF…