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

//插入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不会对原对象有任何影响,且其生命周期只在这个函数内,出了这个函数就自动调用析构函数销毁了。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

第二十二章 Maven

一、Maven 1. Maven 简介 Maven 是一个项目管理工具&#xff0c;可以对 Java 项目进行自动化的构建和依赖管理。Maven 在美国是一个口语化的词语&#xff0c;代表专家、内行的意思&#xff0c;约等于北京话中的老炮儿。有老炮儿在身边&#xff0c;项目经理可谓得心应手。 项…

Redis的5大常见数据类型的用法

上一篇文章我们讲了Redis的10大应用场景&#xff0c;这一篇文章就针对Redis的常用数据结构进行一个说明&#xff0c;通过示例的形式演示每一种数据结构如何使用。 当涉及Redis的数据操作时&#xff0c;不同数据类型对应的不同数据结构&#xff0c;如下就对5大常用的数据类型进行…

[每周一更]-第92期:Go项目中的限流算法

这周五在清明假期内&#xff0c;提前更新文章 很多业务会有限流的场景&#xff0c;比如活动秒杀、社区搜索查询、社区留言功能&#xff1b;保护自身系统和下游系统不被巨型流量冲垮等。 在计算机网络中&#xff0c;限流就是控制网络接口发送或接收请求的速率&#xff0c;它可防…

k8s 部署 canal 集群,RocketMQ 模式

k8s 部署 canal 集群&#xff0c;RocketMQ 模式 k8s 部署 canal 集群&#xff0c;RocketMQ 模式前提MySQLRocketMQ制作 canal-admin、canal-server 镜像 部署 zookeeper部署 canal-admin部署 canal-server测试 k8s 部署 canal 集群&#xff0c;RocketMQ 模式 前提 MySQL 开启…

idea2023.2.1 java项目-web项目创建-servlet类得创建

如何创建Java项目 1.1 方式1&#xff1a; 1.2 方式&#xff1a; 1.3 方式 如何创建web项目 方式 ----- 推荐 如何创建servlet类 复制6 中得代码 给servlet 配置一个路径 启动tomcat 成功了

Plonky2.5:在Plonky2中验证Plonky3 proof

1. 引言 Plonky2.5为QED Protocol团队主导的项目&#xff0c;定位为&#xff1a; 在Plonky2 SNARK中验证Plonky3 STARK proof。 从而实现Plonky系列的递归证明。 开源代码实现见&#xff1a; https://github.com/QEDProtocol/plonky2.5https://github.com/Plonky3/Plonky3&a…

go库x/text缺陷报告CVE-2022-32149的处理方案

#问题描述 go库 golang.org/x/text &#xff0c;注意这里不是go的源码&#xff0c; 在0.3.8版本之前存在一个缺陷(Vulnerability) 缺陷ID CVE-2022-32149 具体描述 攻击者可以通过制作一个Accept-Language报头来导致拒绝服务。 具体的原因是&#xff0c;在解析这个Accept-L…

Scala第十九章节(Actor的相关概述、Actor发送和接收消息以及WordCount案例)

Scala第十九章节 章节目标 了解Actor的相关概述掌握Actor发送和接收消息掌握WordCount案例 1. Actor介绍 Scala中的Actor并发编程模型可以用来开发比Java线程效率更高的并发程序。我们学习Scala Actor的目的主要是为后续学习Akka做准备。 1.1 Java并发编程的问题 在Java并…

如何通过ArkTS卡片的Canvas自定义绘制能力实现五子棋游戏卡片

介绍 本示例展示了如何通过ArkTS卡片的Canvas自定义绘制能力实现一个简单的五子棋游戏卡片。 使用Canvas绘制棋盘和黑白棋子的落子。通过卡片支持的点击事件进行交互&#xff0c;让用户在棋盘上进行黑白棋子的对局。通过TS的逻辑代码实现五子棋输赢判定、回退等逻辑计算&…

Linux制作C++静态库和动态库并使用示例

创建动态库&#xff1a; 编写源文件&#xff1a; // sub.h 显式调用 #include <iostream>extern "C" int sub(int a, int b);// sub.cpp #include "sub.h"int sub(int a, int b) {return a - b; }// quadrature.h 隐式调用 #include <iostream&…

dhcp中继代理

不同过路由器分配ip了&#xff0c;通过一台服务器来代替&#xff0c;路由器充当中继代理功能&#xff0c;如下图 服务器地址&#xff1a;172.10.1.1/24 配置流程&#xff1a; 1.使能dhcp功能 2.各个接口网关地址&#xff0c;配置dhcp中继功能 dhcp select relay &#xff0…

redis---位图Bitmap和位域 Bitfield

位图是字符串类型的拓展&#xff0c;可以使用一个string类型来模拟一个Bit数组。数组的下标就是偏移量&#xff0c;值只有0和1&#xff0c;也支持一些位运算&#xff0c;比如与或非&#xff0c;异或等等&#xff0c;它们的应用场景非常广泛比如可以用来记录用户的签到情况&…

MySQL之索引详细总结

索引简介 索引是帮助MySQL高效获取数据的数据结构(有序)。在数据之外&#xff0c;数据库系统还维护着满足特定查找算法的数据结构&#xff0c;这些数据结构以某种方式引用(指向)数据&#xff0c;这样就可以在这些数据结构上实现高级查法&#xff0c;这种数据结构就是索引 为什…

【星计划★C语言】c语言初相识:探索编程之路

&#x1f308;个人主页&#xff1a;聆风吟_ &#x1f525;系列专栏&#xff1a;星计划★C语言、Linux实践室 &#x1f516;少年有梦不应止于心动&#xff0c;更要付诸行动。 文章目录 &#x1f4cb;前言一. ⛳️第一个c语言程序二. ⛳️数据类型2.1 &#x1f514;数据单位2.2 &…

【TB作品】STM32单片机读取大气压强传感器BMP280

文章目录 读取效果kei工程使用方法接线方法源码工程下载 读取效果 kei工程 标准库&#xff1a; 使用方法 将这2个文件加入 main示例&#xff1a; #include "sys.h" #include "delay.h" #include "usart.h" #include <stdio.h> #incl…

在线生成占位图片工具:简便快捷的设计利器

title: 在线生成占位图片工具&#xff1a;简便快捷的设计利器 date: 2024/4/4 17:36:41 updated: 2024/4/4 17:36:41 tags: 占位图片网页设计开发工具图片生成页面布局效率提升预览调整 在网页开发或设计过程中&#xff0c;经常会遇到需要临时使用占位图片的情况。占位图片是指…

flutter官方案例context_menus【搭建与效果查看】【省时】

案例地址 https://github.com/flutter/samples/tree/main/context_menus 1&#xff1a;运行查看有什么可以快捷使用的&#xff0c;更新了些什么&#xff0c;可不可以直接复制粘贴 主要内容&#xff1a;在web端中模拟手机类型的点击长按操作&#xff0c;不能直接运行在安卓与io…

专升本--python运算符总结

运算优先级 同一个等级是没有先后顺序的&#xff0c;此外&#xff0c;赋值语言的先后问题&#xff1a; 赋值的顺序从上往下&#xff0c;同一行一般都是代表同时进行赋值&#xff0c;如图所示&#xff1a; 一.and A and B&#xff0c;若A,B有任意一个为假&#xff08;0&#x…

论文笔记:Teaching Large Language Models to Self-Debug

ICLR 2024 REVIEWER打分 6666 1 论文介绍 论文提出了一种名为 Self-Debugging 的方法&#xff0c;通过执行生成的代码并基于代码和执行结果生成反馈信息&#xff0c;来引导模型进行调试不同于需要额外训练/微调模型的方法&#xff0c;Self-Debugging 通过代码解释来指导模型识…