C++实现vector

news2024/11/15 17:37:53

目录

前言

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

//插入insert
		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 : 2 * capacity());
				//刷新pos
				pos = _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.coloradmin.cn/o/1568495.html

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

相关文章

flink源码编译-job提交

1、启动standalone集群的taskmanager standalone集群中的taskmanager启动类为 TaskManagerRunner 2 打开master启动类 通过 ctrln快捷键&#xff0c;找到、并打开类&#xff1a; org.apache.flink.runtime.taskexecutor.TaskManagerRunner 3 修改运⾏配置 基本完全按照mas…

高等数学基础篇之导数与微分的运算法则

导数与微分&#xff1a; 一、导数基本公式 二、微分基本公式 三、导数运算法则 四、微分运算法则 一、导数基本公式 二、微分基本公式 三、导数运算法则 四、微分运算法则 有理运算法则 设f(x), g(x)在x处可导&#xff0c;则&#xff1a; 复合函数运算法则 设 yf(u), ug…

【JavaScript】函数 ① ( 函数引入 | 函数声明 | 函数调用 )

文章目录 一、JavaScript 函数1、函数引入2、函数声明3、函数调用4、代码示例 - 函数声明调用 一、JavaScript 函数 1、函数引入 JavaScript 代码编写时 , 会遇到 定义 大量相同或相似代码的 场景 , 这些代码可能需要重复使用 , 这种情况下就需要 将 这些代码 定义在 函数 中 ;…

解决Vue中仓库持久化的问题,不借助插件用原生JS实现仓库持久化。了解仓库的插件机制、监听的时机

1、演示 前言&#xff1a;目前Vue有两种仓库&#xff0c;一种是Vuex&#xff0c;一种是Pinia&#xff0c;懂得都懂&#xff0c;这里就不详细介绍这两者的区别了 2、什么是持久化 仓库里面的数据是需要跨越页面周期的&#xff0c;当页面刷新之后数据还在&#xff0c;在默认情况下…

NoSQL之Redis

目录 一、关系型数据库与非关系型数据库 1.关系数据库 2.非关系数据库 2.1非关系型数据库产生背景 3.关系型数据库与非关系型数据区别 &#xff08;1&#xff09;数据存储方式不同 &#xff08;2&#xff09;扩展方式不同 &#xff08;3&#xff09;对事物性的支持不同 …

日常生活中使用的 4 个核心开发工具

长话短说 本文列出了 2024 年我作为开发人员在日常生活中最常用的 4 个工具。✅ 这些工具旨在提高您的编辑技能、终端导航、笔记以及在应用程序容器化之外使用 Docker。另外&#xff0c;最后我还给大家准备了一个小惊喜。 如果您没有使用本文中至少提到的 1-2 个工具&#xf…

银行数字化转型导师坚鹏:银行数字化转型必知的3大客户分析维度

银行数字化转型需要进行客户分析&#xff0c;如何进行客户分析呢&#xff1f;银行数字化转型导师坚鹏认为至少从客户需求分析、客户画像分析、客户购买行为分析3个维度进行客户分析。 1.客户需求分析 银行数字化转型需要了解客户需求&#xff0c;不同年龄段的客户有不同的需求…

医院云HIS系统源码,二级医院、专科医院his系统源码,经扩展后能够应用于医联体/医共体

基于云计算技术的B/S架构的HIS系统&#xff0c;为医疗机构提供标准化的、信息化的、可共享的医疗信息管理系统&#xff0c;实现医患事务管理和临床诊疗管理等标准医疗管理信息系统的功能。 系统利用云计算平台的技术优势&#xff0c;建立统一的云HIS、云病历、云LIS&#xff0…

echarts 地图 自己圈地图 乡镇街道

这个是方式是我实在不愿意做的&#xff01; 如果有现成的最好&#xff0c;没有办法的情况下再用这个东西。 今天公司有一个项目&#xff0c;地方划分了一块区域&#xff0c;但是国家没有审核&#xff0c;但是项目里面用到了一个地图展示数据&#xff01;然后就需要我们自己把…

vulhub中Apache Solr 远程命令执行漏洞复现(CVE-2019-0193)

Apache Solr 是一个开源的搜索服务器。Solr 使用 Java 语言开发&#xff0c;主要基于 HTTP 和 Apache Lucene 实现。此次漏洞出现在Apache Solr的DataImportHandler&#xff0c;该模块是一个可选但常用的模块&#xff0c;用于从数据库和其他源中提取数据。它具有一个功能&#…

Tailscale:随时随地远程和使用服务器

文章目录 Tailscale是什么&#xff1f;Tailscale能做什么&#xff1f;1、传输文件2、远程开发3、代理 Tailscale怎么用&#xff1f;Windows下安装OpenSSH在线安装离线安装连接SSH服务器 Reference相关阅读 彩蛋&#xff1a;Pycharm远程连接服务器并运行代码 Tailscale是什么&am…

10 年跟踪 Hacker News 招聘贴,解读科技行业变迁

Hackers News (HN) 是国外程序员最喜欢逛的论坛。能登上首页的帖子类似于上了新浪微博。因为其巨大的程序员访问量&#xff0c;因此也成为了公司招聘的渠道。久而久之 HN 招聘帖还形成了专门的标题格式 Ask HN: Who is hiring? 正好有人通过 Ask HN 来分析技术趋势&#xff0c…

如何(关闭)断开 Websocket 连接:简单易懂的实现指南

WebSocket 协议提供了一条用于 Web 应用程序中双向通讯的高效通道&#xff0c;让服务器能够实时地向客户端发送信息&#xff0c;而无需客户端每次都发起请求。本文旨在探讨有关结束 WebSocket 连接的适当时机&#xff0c;内容包括协议的基础知识、如何结束连接、一些使用场景&a…

本地运行github上下载的项目--接Git入门篇

1.了解项目 这是一个基于Spring Boot 和 Mybatis Plus 构建的Java项目&#xff0c;很经典的外卖项目&#xff0c;参考b站的黑马瑞吉外卖。 2.构建项目 SpringBoot项目&#xff0c;首先下载一些常见的项目要求的组件。然后配置如下&#xff1a; 看README&#xff0c;在阅读该…

深入理解计算机系统 家庭作业 2.80

/* 网上很多都没说清楚到底出题人是什么用意,用意就是既要又要,既要不溢出,又要不丢失精度.所以就分开处理,在丢失之前把丢失的部分保存下来,然后两部分算好再相加. 可以先看一下我的2.79题 用的是先乘后除 会溢出 符合题意 2.80要求的是先除后成 不会溢出 但会丢失精度 核…

1.3 操作系统的运行机制、中断与异常、系统调用

一、操作系统的运行机制 知识框图&#xff1a; &#xff08;一&#xff09;程序 内核程序&#xff1a;内核程序是操作系统的核心部分&#xff0c;需要在内核模式下运行&#xff0c;负责管理计算机的硬件资源&#xff0c;如处理器、内存、存储设备和输入输出设备。内核程序还负…

自动驾驶中各种坐标系辨析

坐标系辨析 0. 地球椭圆体1. 大地坐标系2. eci地心惯性坐标系3. 地心地固坐标系(ECEF坐标系&#xff0c;E系)4. 站心坐标系(ENU坐标系)5. UTM坐标系6. LTM坐标系7. IMU坐标系8. 代码部分8.1 LLA(大地坐标系坐标、经纬度海拔)坐标转LTM系(ENU系)下的三维笛卡尔坐标8.2 LLA坐标转…

Coursera上Learning Linux for LFCA Certification专项课程01:Linux Fundamentals 学习笔记

Linux Fundamentals Course Certificate 本文是 Linux Fundamentals 这门课的学习笔记&#xff0c;如有侵权&#xff0c;请联系删除。 文章目录 Linux FundamentalsWeek 01: Linux Operating SystemLearning Objectives Specialization OverviewHistory of LinuxQuiz: Hist…

公众号搜索被降权后多久能恢复?

公众号搜索被降权后的恢复时间是一个复杂的问题&#xff0c;它涉及到多种因素的综合考量。首先&#xff0c;违规的严重程度是一个重要的因素。如果违规行为较为轻微&#xff0c;可能只需要较短的时间就能恢复搜索权重;而如果违规行为较为严重&#xff0c;可能需要更长的时间&am…

2023年CSP-J第一轮题目讲解

大家好&#xff0c;我是极风。由于当年的初赛考的很差&#xff08;没考过70分&#xff09;&#xff0c;所以现在打算拿出来再细看一下。 一、 单项选择题&#xff08;共15题&#xff0c;每题2分&#xff0c;共计30分&#xff1a;每题有且仅有一个正确选项&#xff09; 1. 在…