C++——vector介绍及其简要模拟实现

vector的介绍

此主题介绍转载自(https://cplusplus.com/reference/vector/vector/)

1.vector是一个表示可变大小数组的序列容器

2.vector同数组一样,采用连续存储空间来存储元素,这样可以用下标来对vector中的元素进行访问,但是vector的大小可以动态改变,,且可以其元素被容器vector自动处理。

3.从本质上讲,vector使用动态分配数组来存储器元素,当有元素插入的时候,这个数组需要重新分配大小,然后再将全部元素移入到这个数组里,但是这个过程及其消耗时间,所以为了解决这个问题,vector并不会每次都重新分配大小。

vector的使用/用法

数组的创建

vector <int> v1;//创建一个整型数组v1
vector <int> v2(10,0);//初始化一个数组,count nums  存放count个nums
vector<int> v5(v4);//将v4中的元素拷贝给v5

vector iterator 迭代器的使用

vector<int> v3(v2.begin(),v2.end());//string类和vector类的的迭代器是互通的
string str("hello world");
vector<int> v4(str.begin(), str.end());
vector<int> v5(v4);vector<int>::iterator it = v4.begin();//同时也可以进行迭代器,实现循环遍历
while (it != v4.end())
{cout << *it << " ";++it;
}
cout << endl;for (auto e : v5)
{cout << e << " ";
}
cout << endl;

vector空间增长相关函数

vector<int> v;
v.reserve(100);//reserve改变的是capacity
v.resize(100);//reserve改变的是size 若仅开拓空间,那么仍然不能使用v.size();//读取size
v.capacity();//读取capacity

vector的增删查改

vector<int> v;
//尾插
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);//尾删
v.pop_back()//查找
auto it=find(v.begin(),v.end(),3);//first last dest(firts和last都是迭代器,dest是查找的目标,会返回查找目标的下标)//删除
it =find(v.begin(),v.end(),3);
v.erase(it);//删除找到需要删除的数据的下标,然后进行删除//清除数据
v.clear();//释放空间呢?
v.shrink_to_fit();//同时也能按照数组下标去访问
for(int i=0;i<v.size();i++)
{cout<<v[i]<<endl;
}

vector类和string类的函数用法基本相同,所以这里不作过多的解释,用法也很简单,详细可以参考(https://cplusplus.com/reference/vector/vector/)


vector简要模拟

首先我们要知道vector实现的底层逻辑。找其源代码

可以知道其是进行指针的初始化,模板命名重命名为' iterator ' ' T* == iterator '

 大致模板

namespace an
{template<class T>class vector {public:typedef T* iterator;typedef const T* const_iterator;iterator begin()iterator end()vector(){}vector(size_t n,const T& val=T());vector(const vector<T>& v);void swap(vector<T>& v);vector<T>& operator=(vector<T> tmp);~vector()void reserve(size_t n);void resize(size_t n,const T& val=T());void push_back(const T& x)T& operator[](size_t pos)const T& operator[](size_t pos) constsize_t capacity();size_t size();void insert(iterator& pos, const T& x);iterator erase(iterator pos);private:iterator _start;//原生指针,其实就是T* iterator _finish;iterator _endofstorage;};
}

初始化

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

获取大小/容量

size_t size() const
{return _finish-_start;//指针相减就是个数
}size_t capacity()const
{return _endofstorage-_start;
}

迭代器开头/结尾

iterator begin()
{return _start;
}
iterator end()
{return _finish;
}

开拓空间/重新定义空间

void reserve(size_t n)
{if(n>capacity){size_t sz=size();T* tmp=new T[n];//扩容,需要先开辟一个符合大小的空间,然后再拷贝进去if(_start)//如果拷贝的空间内不为空{for(size_t i=0;i<sz;i++){tmp[i]=_start[i];//由于是指针,所以需要深拷贝,memcpy仅能支持浅拷贝}delete[] _start;//清除空间}    _start=tmp;_finish=_start+sz;_endofstorage=_start+n;}
}void resize(size_t n,const T& val=T())
{if(n<=size())    {        _finish=_start+n;}else{reserve(n);while(_finish<_start+n)    {*_finish=val;++_finish;}    }
}    

尾插

void push_back(const T& x)
{if(_finish==_endofstorage)//扩容里的代码也可以用reserve(capacity()==0?4:capacity()*2)来代替{size_t sz=size();size_t cp=capacity()==0?4:22*capacity();T* tmp=new T[cp];if(_start!=nullptr){memcpy(tmp,_start,sizeof(T)*size());delete[] _start;}_start=tmp;_finish=_start+sz;_endofstorage=_start+cp;}    *_finish=x;//最后一个位置赋值++_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 insert(iterator pos,const T& x)
{assert(pos>=_start);assert(pos<=_finish);if(_finish==_endofstorage){size_t len=pos-_start;reserve(capacity() == 0 ? 4 : capacity() * 2);pos=_start+len;//注意,这里更新后的start指向的空间和原来的pos不一样,需要进行更新}iterator end=_finish-1;while(end>=pos){*(end+1)=*end;--end;}*pos=x;++_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(const vector<T>& v)
{reserve(v.capacity());for(auto e: v){push_back(e);}
}void swap(vector<T>& v)
{std::swap(_start, v._start);std::swap(_finish, v._finish);std::swap(_endofstorage, v._endofstorage);
}
vector<T>& operator=(vector<T> tmp)
{swap(tmp);//有this指针,直接作用于要作用的对象return *this;
}

迭代器初始化

template<class InputIterator>
vector(InputIterator first, InputIterator last)//迭代器初始化
{while (first != last){push_back(*first);++first;}
}

vector初始值初始化

vector(size_t n,const T& val=T())//n个数据去初始化
{reserve(capacity());for (size_t i = 0; i < n; i++){push_back(val);}
}
//为了与迭代器的模板类型进行区分,所以这里形参T加上了' & ' 符号

统一初始化

因为上述有多个构造函数,为了简化代码不出现多个初始化列表,所以在声明的时候就进行定义

private://原生指针,其实就是T* iterator _start=nullptr;//指向数据的开始 iterator _finish=nullptr;//指向数据的结束iterator _endofstorage=nullptr;//指向空间位置的结束

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

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

相关文章

Unity ML-Agent

介绍: 环境搭建 待为完序

手机便签中可以打勾的圆圈或小方块怎么弄?

在日常的生活和工作中&#xff0c;很多网友除了使用手机便签来记录灵感想法、读书笔记、各种琐事、工作事项外&#xff0c;还会用它来记录一些清单&#xff0c;例如待办事项清单、读书清单、购物清单、旅行必备物品清单等。 在按照记录的清单内容来执行的时候&#xff0c;为了…

进程间通信(IPC)的几种方式

进程间通信&#xff08;IPC&#xff09; 1.常见的通信方式2.低级IPC方法文件 3.常用于本机的IPC机制3.1无名管道pipe3.2命名管道FIFO3.3消息队列MessageQueue3.4共享内存SharedMemory3.5信号量Semaphore3.6信号Signal3.7unix域套接字 4.不同计算机上的IPC机制5.IPC机制的数据拷…

LeetCode150道面试经典题--找出字符串中第一个匹配项的下标(简单)

1.题目 给你两个字符串 haystack 和 needle &#xff0c;请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标&#xff08;下标从 0 开始&#xff09;。如果 needle 不是 haystack 的一部分&#xff0c;则返回 -1 。 2.示例 3.思路 回溯算法&#xff1a;首先将…

百度智能云:千帆大模型平台接入Llama 2等33个大模型,上线103个Prompt模板

大家好&#xff0c;我是herosunly。985院校硕士毕业&#xff0c;现担任算法研究员一职&#xff0c;热衷于机器学习算法研究与应用。曾获得阿里云天池比赛第一名&#xff0c;CCF比赛第二名&#xff0c;科大讯飞比赛第三名。拥有多项发明专利。对机器学习和深度学习拥有自己独到的…

Rest 优雅的url请求处理风格及注意事项

&#x1f600;前言 本篇博文是关于Rest 风格请求的应用和注意事项&#xff0c;希望能够帮助到您&#x1f60a; &#x1f3e0;个人主页&#xff1a;晨犀主页 &#x1f9d1;个人简介&#xff1a;大家好&#xff0c;我是晨犀&#xff0c;希望我的文章可以帮助到大家&#xff0c;您…

08-3_Qt 5.9 C++开发指南_Graphics View绘图架构

文章目录 1. 场景、视图与图形项1.1 场景1.2 视图1.3 图形项 2. Graphics View 的坐标系统2.1 图形项坐标2.2 视图坐标2.3 场景坐标2.4 坐标映射 3. Graphics View 相关的类3.1 QGraphicsView 类的主要接口函数3.2 QGraphicsScene 类的主要接口函数3.3 图形项 4. 实例介绍 1. 场…

【2023 华数杯全国大学生数学建模竞赛】 C题 母亲身心健康对婴儿成长的影响 45页论文及python代码

【2023 华数杯全国大学生数学建模竞赛】 C题 母亲身心健康对婴儿成长的影响 45页论文及python代码 1 题目 母亲是婴儿生命中最重要的人之一&#xff0c;她不仅为婴儿提供营养物质和身体保护&#xff0c; 还为婴儿提供情感支持和安全感。母亲心理健康状态的不良状况&#xff0c…

Java线程池

线程池 1. 概念2. 工作流程3. ThreadPoolExecutor参数 1. 概念 线程池是一种利用池化技术思想来实现的线程管理技术&#xff0c;主要是为了复用线程、便利地管理线程和任务、并将线程的创建和任务的执行解耦开来。我们可以创建线程池来复用已经创建的线程来降低频繁创建和销毁…

在pycharm中使用Git上传代码到Gitee/GitHub(适合新手小白的超级详细步骤讲解)

目录 一、在pycharm中下载gitee/github插件二、注册自己的Gitee / Githhub账号三、创建仓库三、选择想要上传的代码文件四、修改代码后上传到Gitee/GitHub 因为Gitee和GitHub使用方法差不多&#xff0c;所以本文以将代码上传到Gitee为例&#xff0c;GitHub操作类似。 一、在py…

vivado tcl创建工程和Git管理

一、Tcl工程创建 二、Git版本管理 对于创建完成的工程需要Git备份时&#xff0c;不需要上传完整几百或上G的工程&#xff0c;使用tcl指令创建脚本&#xff0c;并只将Tcl脚本上传&#xff0c;克隆时&#xff0c;只需要克隆tcl脚本&#xff0c;使用vivado导入新建工程即可。 优…

【机器学习2】什么是Jupyter notebook 新手使用Jupter notebook

什么是Jupyter notebook? Jupyter Notebook&#xff08;此前被称为 IPython notebook&#xff09;是一个交互式笔记本&#xff0c;支持运行 40 多种编程语言。 Jupyter Notebook 的本质是一个 Web 应用程序&#xff0c;便于创建和共享程序文档&#xff0c;支持实时代码&#x…

list的使用和模拟实现

目录 1.list的介绍及使用 1.1 list的介绍 1.2 list的使用 1.2.1 list的构造 1.2.2 list iterator的使用 1.2.3 list capacity 1.2.4 list element access 1.2.5 list modifiers 2.为什么使用迭代器&#xff1f; 3.list的模拟实现 3.1完整代码 3.2代码解析 4.list与…

大数据-玩转数据-Flink-Transform

一、Transform 转换算子可以把一个或多个DataStream转成一个新的DataStream.程序可以把多个复杂的转换组合成复杂的数据流拓扑. 二、基本转换算子 2.1、map&#xff08;映射&#xff09; 将数据流中的数据进行转换, 形成新的数据流&#xff0c;消费一个元素并产出一个元素…

iOS开发-WebRTC本地直播高分辨率不显示画面问题

iOS开发-WebRTC本地直播高分辨率不显示画面问题 在之前使用WebRTC结合ossrs进行推流时候&#xff0c;ossrs的播放端无法看到高分辨率画面问题。根据这个问题&#xff0c;找到了解决方案。 一、WebRTC是什么 WebRTC是什么呢&#xff1f; WebRTC (Web Real-Time Communicatio…

【学习FreeRTOS】第4章——FreeRTOS任务创建与删除

1.任务创建和删除的API函数 任务的创建和删除本质就是调用FreeRTOS的API函数 动态方式创建任务——xTaskCreate()静态方式创建任务——xTaskCreateStatic()删除任务——vTaskDelete() 动态创建任务&#xff1a;任务的任务控制块以及任务的栈空间所需的内存&#xff0c;均由 F…

[Kubernetes]Kubeflow Pipelines - 基本介绍与安装方法

1. 背景 近些年来&#xff0c;人工智能技术在自然语言处理、视觉图像和自动驾驶方面都取得不小的成就&#xff0c;无论是工业界还是学术界大家都在惊叹一个又一个的模型设计。但是对于真正做过算法工程落地的同学&#xff0c;在惊叹这些模型的同时&#xff0c;更多的是在忧虑如…

【论文阅读】Deep Instance Segmentation With Automotive Radar Detection Points

基于汽车雷达检测点的深度实例分割 一个区别&#xff1a; automotive radar 汽车雷达 &#xff1a; 分辨率低&#xff0c;点云稀疏&#xff0c;语义上模糊&#xff0c;不适合直接使用用于密集LiDAR点开发的方法 &#xff1b; 返回的物体图像不如LIDAR精确&#xff0c;可以…

Redis追本溯源(四)集群:主从模式、哨兵模式、cluster模式

文章目录 一、主从模式1.主从复制——全量复制2.主从复制——增量复制 二、哨兵模式1.实时监控与故障转移2.Sentinel选举领导者 三、cluster模式1.三种分片方案2.cluster模式 Redis 有多种集群搭建方式&#xff0c;比如&#xff0c;主从模式、哨兵模式、Cluster 模式。 一、主…

15.4 【Linux】可唤醒停机期间的工作任务

15.4.1 什么是 anacron anacron 并不是用来取代 crontab 的&#xff0c;anacron 存在的目的就在于我们上头提到的&#xff0c;在处理非24 小时一直启动的 Linux 系统的 crontab 的执行&#xff01; 以及因为某些原因导致的超过时间而没有被执行的调度工作。 其实 anacron 也是…