C++实现vector

目录

前言

1.成员变量

2.成员函数

2.1构造函数

2.2析构函数

2.3begin,end

2.4获取size和capacity

2.5函数重载【】

2.6扩容reserve

2.7resize

2.8insert

2.9删除

2.10尾插、尾删

3.0拷贝构造函数

3.1赋值运算符重载


前言

自主实现C++中vector大部分的功能可以使我们更好的理解并使用vector。本篇我们只会实现最常用的,因为我们的目的不是要超越或则弄一个一模一样的,而是去理解。

1.成员变量

我们先来看看vector中的成员变量,在这里我们定义了3个成员变量,并为了安全性的考量给它们的权限定位private。我们知道vector是顺序表的意思,而顺序表的底层是由数组来实现的,所以我们第一个变量_start的意思是数组的头部位置,大家可能会很疑惑,数组的头部位置不是应该用指针吗,这里为什么用迭代器类型呢?

其实这里没啥门道,我们得知道迭代器的本质类型其实是由其它类型的typedef过来的,像这里我们这样用是因为我们typedef的就是指针类型。

T是我们类模板的类型,这样可以保证我们的vector不受类型限制,而T*不就是我们的指针类型吗,这里typedef了两个,第二个我们是用const修饰的,这是因为会有将vector定义成const属性的情况。

知道了这些之后我们就好理解了,_start指向开头,_finish指向结尾,_endofstorage指向空间边界。

2.成员函数

2.1构造函数

因为我们的构造不涉及深拷贝以及动态开辟空间,而且我们的成员变量都已经附上初始值了,所以单纯的无参构造就不需要写任何东西了。

2.2析构函数

我们的析构函数也很简单,我们只需要delete掉_start,然后将这3个变量赋为空就行了。

2.3begin,end

begin和end我们要写两种的原因跟上面一样,是为了应对常属性的情况。

2.4获取size和capacity

这两个实现也很简单,光看代码就能理解。

2.5函数重载【】

这个操作也很简单,我们只需要断言一下pos是否超出有效范围,正常的话就返回那个值就可以了。

2.6扩容reserve

reserve是我们的扩容操作,所以我们先看看是否大于我们的空间,大就扩容,小就不操作,

我们先定义一个old_size来记录我们的原先数组的有效元素个数,然后再定义一个tmp来充当中转站,然后用for循环直接将_start里的每一个元素赋值给tmp,然后就可以将原先的数组空间清楚了,然后我们再把_start跟tmp相等,_finish、_endofstorage调成对应的就可以了。出这个函数我们的tmp指针是会自动销毁的,但空间是动态开辟的所以不需要担心泄露或野指针的问题。

2.7resize

resize可以控制我们有效元素的个数,如果扩大的个数超过空间大小还会进行扩容操作,这里唯一需要解释一下的就是第二个参数了,第二个参数的设计很巧妙,我们知道第二个参数是为了应付增加有效元素个数准备的,比如这个参数你传的是0,那么就用0来填补数组,所以问题也就来了,我们除了基本类型以外还有可能是类的类型,而这两种类型给的缺省值方式是不一样的,那要怎么做到一个统一呢?

C++提供了一种方法,就是创建匿名对象,C++是支持int a = int(),这种写法的,所以我们就可以利用这一点将基本类型和引用类型的差异给解决。

2.8insert

//插入insertvoid insert(iterator pos, const T& val){assert(pos >= _start);assert(pos <= _finish);//扩容if (_finish == _endofstorage){size_t len = pos - _start;reserve(capacity() == 0 ? 4 : 2 * capacity());//刷新pospos = _start + len;}//插入数据iterator it = _finish - 1;while (pos <= it){*(it + 1) = *it;it--;}*pos = val;_finish++;}

插入操作也很简单,我们第一步要进行断言操作,你总不能随便传一个下标值吧,然后我们要判断一下是否需要扩容,扩容阶段结束后就到了插入数据的时候了,整个插入过程其实非常朴素,没有什么难点。

2.9删除

删除操作就更简单了,还是先断言,但我们要注意,这次pos不能等于_finish,因为插入操作的情况下,我们的pos如果是_finish可以理解为它是进行尾插,但是删除总不能把'\0'给删除吧。只要理解了这个,剩下的代码就很好理解了,我不说大家都能看懂。

2.10尾插、尾删

尾插和尾删我们都可以采用现代方法来写,也就是吃现成的。

3.0拷贝构造函数

一般的拷贝构造函数我们可以这么去写,这种思路很巧妙代码也很容易看懂。重点是我们下面几种的拷贝构造函数。

这种写法可以支持我们的list像数组一样赋值,因为单参数传参会有隐式类型转换,我们括号里的内容会被转换成initializer_list<T>类型,然后就可以像上一步部一样操作了。注意这里是用auto&,这是为了避免像string这种类型出差错而采用的别名。

上面这种是因为STL标准库中vector也有这样一中重载写法,它是采用迭代器来进行传值,first和last都是我们的迭代器类型。写成模板是因为迭代器还有一种const属性的。

这是重载的另一种版本,开n个空间的大小,用第二个参数自动填充,为什么要写两个呢,第一个n的类型是size_t,第二个n的类型是int,这是因为倘若我们传两个int类型的,如果没有下面这种它就要进行类型转换,但是我们上面还有一种函数模板,所以我们的编译器此时就会去使用那个函数模板,但是那个我们是针对迭代器类型的,所以结果会发生什么大家应该都猜到了吧,所以为了规避那种情况我们就重载了两个方式。

3.1赋值运算符重载

赋值运算符重载我们借用了拷贝构造函数,因为我们的参数是形参且没有使用引用,所以会自动调用拷贝构造函数,然后我们直接交换数据就可以了。由于v是拷贝构造出来的,数以改变v不会对原对象有任何影响,且其生命周期只在这个函数内,出了这个函数就自动调用析构函数销毁了。

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

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

相关文章

红黑树介绍与模拟实现(insert+颜色调整精美图示超详解哦)

红黑树 引言红黑树的介绍实现结点类insert搜索插入位置插入调整当parent为gparent的左子结点当parent为gparent的右子结点 参考源码测试红黑树是否合格总结 引言 在上一篇文章中我们认识了高度平衡的平衡二叉树AVL树&#xff1a;戳我看AVL树详解哦 &#xff08;关于旋转调整的…

Java 7、Java 8常用新特性

目录 Java 8 常用新特性1、Lambda 表达式2、方法引用2.1 静态方法引用2.2 特定对象的实例方法引用2.3 特定类型的任意对象的实例方法引用2.4 构造器引用 3、接口中的默认方法4、函数式接口4.1 自定义函数式接口4.2 内置函数式接口 5、Date/Time API6、Optional 容器类型7、Stre…

(四) 序列化器类使用整理

从一、序列化器类中&#xff0c;或 视图集源码 中&#xff0c; 可以得知&#xff1a; 序列化器类可以接收一个instance &#xff0c;和一个data serializer_obj XxxxSerializer(instance,datarequest.data) &#xff08;更新时&#xff0c;instance相当于原…

java 溯本求源之基础(十二)之 Security--jarsigner

目录 1. 签名JAR文件的重要性 2. jarsigner的基本用法 3. 签名过程详解 3.1. 生成摘要 3.2. 创建签名文件 3.3. 生成签名块文件&#xff1a; 3.4. 验证过程详解 5. 使用时间戳签名 6. jarsigner在实际开发中的应用 示例1&#xff1a;为Web应用签名 示例2&#xff1a;为…

云原生技术精选:探索腾讯云容器与函数计算的最佳实践

文章目录 写在前面《2023腾讯云容器和函数计算技术实践精选集》深度解读案例集特色&#xff1a;腾讯云的创新实践与技术突破精选案例分析——Stable Diffusion云原生部署的最佳实践精选集实用建议分享总结 写在前面 在数字化转型的浪潮下&#xff0c;云计算技术已成为企业运营…

【Vue.js 3.0】NProgress 进度条

简介 在 Vue 3 中使用 NProgress&#xff0c;你需要先安装 NProgress&#xff0c;然后在你的 Vue 应用中引入它&#xff0c;并在适当的生命周期钩子或路由守卫中调用它的方法。以下是一个简单的例子来展示如何在 Vue 3 应用中集成 NProgress 首先&#xff0c;你需要安装 NPro…

Kafka入门到实战-第五弹

Kafka入门到实战 Kafka常见操作官网地址Kafka概述Kafka的基础操作更新计划 Kafka常见操作 官网地址 声明: 由于操作系统, 版本更新等原因, 文章所列内容不一定100%复现, 还要以官方信息为准 https://kafka.apache.org/Kafka概述 Apache Kafka 是一个开源的分布式事件流平台&…

基于springboot+vue实现的酒店客房管理系统

作者主页&#xff1a;Java码库 主营内容&#xff1a;SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app等设计与开发。 收藏点赞不迷路 关注作者有好处 文末获取源码 技术选型 【后端】&#xff1a;Java 【框架】&#xff1a;spring…

昇腾训练执行与推理部署系列 入门: 1.开启异腾AI之旅

一、1认识CANN 1、昇腾AI基础软硬件平台介绍2、CANN逻辑架构介绍 1、昇腾AI基础软硬件平台介绍 2、CANN逻辑架构介绍

普联一面4.2面试记录

普联一面4.2面试记录 文章目录 普联一面4.2面试记录1.jdk和jre的区别2.java的容器有哪些3.list set map的区别4.get和post的区别5.哪个更安全6.java哪些集合类是线程安全的7.创建线程有哪几种方式8.线程的状态有哪几种9.线程的run和start的区别10.什么是java序列化11.redis的优…

商品购买过程中,库存的抵扣过程是怎样的?如何防止超卖?

在商品购买的过程中&#xff0c;库存的抵扣过程&#xff0c;一般操作如下&#xff1a; 1、select根据商品id查询商品的库存。 2、根据下单的数量&#xff0c;计算库存是否足够&#xff0c;如果存库不足则抛出库存不足的异常&#xff0c;如果库存足够&#xff0c;则减去扣除的…

mysql+keepalive+lvs搭建的数据库集群实验

前提条件&#xff1a;准备5台计算机&#xff0c;且网络互通 1、客户端 yum groups -y install mariadb-client ip 192.168.0.5 2、lvs1 yum-y install ipvsadm keepalived ip 192.168.0.1 keepalivedvip 192.168.0.215 /etc/hosts 解析192.168.0.1 主机名 3、lvs2 yum-y i…

为什么android创建Fragment推荐用newInstance

FullScreenDialogFragment使用newInstance方法不是因为它是一个单例&#xff0c;而是因为这是创建DialogFragment实例并同时提供参数的一种标准模式。这种模式通常称为静态工厂方法模式&#xff0c;在Android开发中被广泛使用&#xff0c;尤其是用于Fragment的实例化。 newIns…

前视声呐目标识别定位(五)-代码解析之修改声呐参数

前视声呐目标识别定位&#xff08;一&#xff09;-基础知识 前视声呐目标识别定位&#xff08;二&#xff09;-目标识别定位模块 前视声呐目标识别定位&#xff08;三&#xff09;-部署至机器人 前视声呐目标识别定位&#xff08;四&#xff09;-代码解析之启动识别模块 …

Java最短路径算法知识点(含面试大厂题和源码)

最短路径算法是计算机科学和图论中的核心问题之一&#xff0c;它旨在找到从一个顶点到另一个顶点或在所有顶点之间的最短路径。这个问题在多种实际应用中都非常重要&#xff0c;如网络路由、交通规划、社交网络分析等。以下是一些与最短路径算法相关的知识点&#xff1a; Dijks…

DHT11温湿度传感器使用视频教程分享

下载地址&#xff1a; 温湿度计(STCDHT11): https://url83.ctfile.com/d/45573183-60623983-9b7f6c?p7526 (访问密码: 7526)

Java常用类和基础API

文章目录 1. 字符串相关类之不可变字符序列&#xff1a;String1.1 String的特性1.2 String的内存结构1.2.1 概述1.2.2 练习类型1&#xff1a;拼接1.2.3 练习类型2&#xff1a;new1.2.4 练习类型3&#xff1a;intern() 1.3 String的常用API-11.3.1 构造器1.3.2 字符串对象的比较…

解决酷狗官网无法播放音乐问题

播放歌曲页面无法播放歌曲&#xff0c;有CORS错误&#xff0c;困扰我很久了。 谷歌浏览器优雅的关闭cors跨域_浏览器关闭跨域-CSDN博客 "C:\Program Files\CatsxpSoftware\Catsxp-Browser\Application\catsxp.exe" --disable-web-security --user-data-dirE:\catsxp…

【学习笔记】java项目—苍穹外卖day10

文章目录 苍穹外卖-day10课程内容1. Spring Task1.1 介绍1.2 cron表达式1.3 入门案例1.3.1 Spring Task使用步骤1.3.2 代码开发1.3.3 功能测试 2.订单状态定时处理2.1 需求分析2.2 代码开发2.3 功能测试 3. WebSocket3.1 介绍3.2 入门案例3.2.1 案例分析3.2.2 代码开发3.2.3 功…

JavaScript之applye、bind和call方法详解

Question Q1 apply()、bind()和call()方法的区别在哪&#xff1f; Q2 apply()和call()的应用场景 Q3 apply()、bind()和call()方法手写实现逻辑 来源 继承自Function.prototype&#xff0c;属于实例方法 console.log(Function.prototype.hasOwnProperty(call)) //trueconsole.l…