模拟实现string类

目录

 

一.构造与析构函数

二.基础小功能的实现

1.clear

2.c_str

3外部对私有的查看

三.实现string的迭代器

四.string的增删查改

1.push_back尾插

1.1reserve扩容

1.2尾插

3.运算符重载+=

4.insert在任意位置插入

5.erase删除

5.1npos的处理

5.2函数的实现

6.find查找

6.1查找字符

6.2查找一个串

7.substr

五.比较运算符的重载

1.流提取

2.流插入!!

3.getline(流插入的变形)


 

一.构造与析构函数

1.定义自己的命名空间,这里我们简便取名为my,防止和std里的string冲突

2.声明成员变量,实现string需要一个指向存储内容的char*指针,_size记录存储内容的长度(不包括\0),_capacity记录开辟的空间大小(同样也不包括\0)

3.声明构造函数,并且实现析构函数,析构函数直接释放掉str申请的内存,并且重置三个成员变量即可,实现比较简单

4.实现默认构造函数

 

 

4.1.首先,我们先实现这个默认构造函数,参数为缺省的一个指向字符串的指针

4.2.先用初始化列表对_size进行初始化,内容的长度与字符串长度一致

4.3.空间大小与长度一致

4.4.申请_capacity+1个空间,给_str

4.5.利用strcpy函数拷贝字符串到申请的空间里面

 

5.实现n个ch的构造函数

申请n+1个空间,然后利用for循环赋值,实现较为简单,不过多讲解,需要注意的是,需要自己手动将_str[_size]赋值为\0,之前的那个默认构造函数因为使用的strcpy函数就不需要

6.实现拷贝构造函数

简单来说,就是申请capacity+1个空间然后进行拷贝,不过多讲解了

 

二.基础小功能的实现

1.clear

clear函数的作业是清空string,由于string是线性结构,所以把_str的第一个元素改为\0,并且将_size改为0,那么在读取的时候,到第一个元素就停止了,就实现了clear

2.c_str

c_str的作用是返回一个指向存储内容的指针,这样就可以使用cout或者printf来打印string的内容了,方便我们查看,并且兼容c语言的功能

3外部对私有的查看

由于外部无法直接查看类的私有成员变量,所以我们可以通过public成员函数的方式来简介提供查看,_size用来查看长度,_capaciti用来查看容量,同时,由于string很像字符数组,所以我们运算符重载了[],方便他人使用

三.实现string的迭代器

begin返回初始位置,也就是_str,end返回最后一个元素的下一个位置,也就是_str+_size,有了迭代器的实现,我们就可以使用范围for来便利string了,效果如下

四.string的增删查改

1.push_back尾插

1.1reserve扩容

在尾插中,要检查空间是否足够,经常会出现扩容的情况,所以把扩容封装成一个函数

这是c加加标准库的解释,我们只完成扩容的情况

只有在n大于空间时,才进行扩容,我们只需要新申请一块空间然后将原来空间的内容拷贝过去就可以了,类似于深拷贝,最后不要忘记释放原有空间

1.2尾插

尾插之前,我们需要先判断空间是否足够,如果_size==_capacity说明空间已经满了,无法再插入,那么我们就需要使用reserve扩容,我们这里实现的是二倍扩容,但是要处理一下特殊情况,也就是_capacity为0的时候,此时如果二倍扩容,那么扩容后的空间也为0,所以,我们这里使用了三目操作符,如果空间为0,就扩容为4,其他情况就二倍扩容,然后插入即可

2.append

append函数通过在string的末尾加字符来扩展字符串,也算是增加的一种,我们只实现加一个串

首先,我们先判断空间是否足够再插入一个字符串,如果不够我们就进行扩容,扩容的逻辑就是二倍扩容,如果二倍不够,那么就扩容到_size+len,接着使用strcpy函数来拷贝一下,最后记得更新size的值,就完成了

3.运算符重载+=

总体来说,和append差不多,我们实现+=一个字符和+=一个字符串

这里就是简单的函数复用,很容易就可以完成

4.insert在任意位置插入

作用就是在pos位置之前插入内容

这里我们实现了两种,在pos位置前插入n个字符和在pos位置前插入一个串

总体来说,思路就是先检查空间,然后把pos之后的内容后移n(n为插入元素的个数)个位置,然后进行插入,最后,一定要记得更新_size的值

5.erase删除

总的来说erase函数的作用就是在第pos个位置,删除len个字符,最后返回这个string对象。

5.1npos的处理

此函数的第二个参数有缺省值,为npos,就是最大的长度,我们可以把npos封装为一个静态成员变量,然后将其再类外初始化为-1,因为size_t是无符号整数,所以他的值将会为size_t的最大值,(在32位系统中,size_t 通常是32位无符号整数,最大值为 2^32 - 1,即 4294967295。在64位系统中,size_t 通常是64位无符号整数,最大值为 2^64 - 1)肯定可以到达字符串末尾

5.2函数的实现

如果删除的长度超出了剩余的长度,那么就是将pos及其后面的位置都删除掉,我们只需要把pos的位置设置为\0,并且更新_size的值就可以了

如果没有超出,那么我们用一个变量end记录要删除的最后一个位置的下一个位置,即pos后第一个不需要被删除的位置,然后进行数据的挪动,如上图代码所示,最后更新_size的值就好了

最后,不要忘记返回这个对象,即*this

6.find查找

find用来查找字符串中匹配的内容,并且返回它的位置

6.1查找字符

我们直接遍历整个字符串,找到就返回它的位置,找不到直接返回npos

6.2查找一个串

在这里,我们可以直接使用strstr函数来加快我们实现的速度,简单说一下strstr函数的作用就是,返回指向 str1 中第一次出现的 str2 的指针,如果 str2 不是 str1 的一部分,则返回 null 指针。

这样,我们如果没找到就返回npos,找到了返回指针相减的值即位置

7.substr

简单来说,就是返回字符串的一部分

实现substr的功能,我们需要先更新len的值,如果长度超过了剩余长度,那么就是返回从pos到剩下的全部,然后,创建一个临时的string类来存储字符串的一部分,最后将它返回,需要注意的是,返回值不能为string&,因为tmp创建在栈中,出了栈会自动析构

五.比较运算符的重载

实现比较运算符的重载,我们一定要学会复用,我们可以先实现一个==(等于)的,那么!==不就是!=(不等于)了吗。以此类推,很快就可以实现了,在这里面,我们使用strcmp函数,它可以帮助我们比较两个字符串的大小,(大于就返回一个>0的数,小于就返回一个小于0的数,等于就直接返回0

六.流插入和流提取的重载

istream是 C++ 标准库中的一个类,用于表示输入流(Input Stream),ostream表示输出流

我们重载流插入和流提取,一定要重载到全局,因为对象一定在>>或者<<的后面,如果直接重载为成员函数,那么第一个参数就被固定为this指针,无法正确使用

1.流提取

流提取直接使用范围for遍历即可

2.流插入!!

这段代码是经过优化后的代码,我在这里需要着重解释一下

首先,进入函数时,我们需要先清除字符串本身的内容,因为流提取的内弄会对原内容进行覆盖std标准库就是这么实现的

然后,我们为了防止输入的串过长,需要不断扩容降低运行效率,我们创建了一个buff数组来存储输入的内容,大小定为1024,然后通过+=的方式来对字符串更新(+=一个串会调用append,里面使用的是一次扩容,能够提高效率)

如果输入的内容过多,buff数组满了,那么就直接+=然后重置i为0,出了循环在判断一下,如果i不是0的话就再+=一次

3.getline(流插入的变形)

流插入是遇到空格或者\n时停止,getline可以自定义遇到停止的内容,所以,实现getlne只需要改变流提取的if判断即可(默认getline是遇到\n停止,即读取一行)

 

 

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

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

相关文章

机器学习之数学基础:线性代数、微积分、概率论 | PyTorch 深度学习实战

前一篇文章&#xff0c;使用线性回归模型逼近目标模型 | PyTorch 深度学习实战 本系列文章 GitHub Repo: https://github.com/hailiang-wang/pytorch-get-started 本篇文章内容来自于 强化学习必修课&#xff1a;引领人工智能新时代【梗直哥瞿炜】 线性代数、微积分、概率论 …

记录一下 在Mac下用pyinstallter 打包 Django项目

安装: pip install pyinstaller 在urls.py from SheepMasterOneToOne import settings from django.conf.urls.static import staticurlpatterns [path("admin/", admin.site.urls),path(generate_report/export/, ReportAdmin(models.Report, admin.site).generat…

UE求职Demo开发日志#23 线性任务系统数据层实现

1 按上期设计创建数据结构&#xff08;做了一些修改&#xff09; USTRUCT(BlueprintType) struct ARPG_CPLUS_API FQuestNode {GENERATED_USTRUCT_BODY()// 记录前置节点IDUPROPERTY(EditAnywhere, BlueprintReadWrite,Category"QuestNode")TArray<int> Prede…

mysql8安装时提示-缺少Microsoft Visual C++ 2019 x64 redistributable

MySQL8.0安装包mysql-8.0.1-winx64进行安装&#xff0c;提示&#xff1a;This application requires Visual Studio 2019 x64Redistributable, Please install the Redistributable then runthis installer again。出现这个错误是因为我们电脑缺少Microsoft Visual C 这个程序&…

K8s 分布式存储后端(K8s Distributed Storage Backend)

K8s 分布式存储后端 在 K8s 中实现分布式存储后端对于管理跨集群的持久数据、确保高可用性、可扩展性和可靠性至关重要。在 K8s 环境中&#xff0c;应用程序通常被容器化并跨多个节点部署。虽然 K8s 可以有效处理无状态应用程序&#xff0c;但有状态应用程序需要持久存储来维护…

生产环境超实用shell脚本一

生产环境超实用shell脚本一 Shell脚本作为一种强大的自动化工具&#xff0c;能够帮助运维人员轻松应对各种复杂的任务。 本文将为您介绍服务器健康检查、日志清理、备份以及监控等多个方面&#xff0c;并详细阐述每个脚本的功能和应用场景&#xff0c;助力您提升运维效率&…

IM 即时通讯系统-46-OpenIM 提供了专为开发者设计的开源即时通讯解决方案

IM 开源系列 IM 即时通讯系统-41-开源 野火IM 专注于即时通讯实时音视频技术&#xff0c;提供优质可控的IMRTC能力 IM 即时通讯系统-42-基于netty实现的IM服务端,提供客户端jar包,可集成自己的登录系统 IM 即时通讯系统-43-简单的仿QQ聊天安卓APP IM 即时通讯系统-44-仿QQ即…

spy-debugger + Charles 调试移动端/内嵌小程序H5

简介说明&#xff1a; PC端可以用F12进行console等进行调试&#xff0c;但移动端App中使用webview就无法进行实时调试&#xff0c;针对这种情况 1. 安装 全局安装 spy-debugger sudo npm install spy-debugger -g // window不用加sudo2. spy-debugger 证书 其实spy-debugg…

深度整理总结MySQL——SQL的执行顺序和流程

SQL的执行顺序和流程 SQL的执行顺序执行一条select语句,发生了什么呢连接器查询缓存解析SQL执行SQL预处理器优化器执行器 总结 SQL的执行顺序 这是一条标准的查询语句: 但实际上并不是从上到下去解析的,真实的执行顺序是: 我们先执行from,join来确定表之间的连接关系&#x…

使用 Ollama 在 Windows 环境部署 DeepSeek 大模型实战指南

文章目录 前言Ollama核心特性 实战步骤安装 Ollama验证安装结果部署 DeepSeek 模型拉取模型启动模型 交互体验命令行对话调用 REST API 总结个人简介 前言 近年来&#xff0c;大语言模型&#xff08;LLM&#xff09;的应用逐渐成为技术热点&#xff0c;而 DeepSeek 作为国产开…

Redis有哪些常用应用场景?

大家好&#xff0c;我是锋哥。今天分享关于【Redis有哪些常用应用场景?】面试题。希望对大家有帮助&#xff1b; Redis有哪些常用应用场景? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 Redis 是一个高性能的键值对存储数据库&#xff0c;它有许多应用场景&…

115,【7】 攻防世界 web fileinclude

进入靶场 试着访问了几个文件&#xff0c;都没得到信息&#xff0c;f12看看源码 还真有 <?php // 检查是否开启了错误显示功能 // ini_get 函数用于获取 PHP 配置选项的值&#xff0c;这里检查 display_errors 选项是否开启 if( !ini_get(display_errors) ) {// 如果错误…

SpringBoot开发(五)SpringBoot接收请求参数

1. SpringBoot接收请求参数 1.1. 获取参数的方式 &#xff08;1&#xff09;通过request对象获取参数   &#xff08;2&#xff09;RequestParam(针对请求头方式为x-www-form-ur lencoded)   &#xff08;3&#xff09;RequestBody(针对请求头方式为application/json)   …

如何理解多态,以及由此引出的抽象类和纯虚函数

文章目录 1. 多态2. 抽象类和纯虚函数 1. 多态 静态多态&#xff1a; 动态多态&#xff1a; #include <iostream> #include <string> using namespace std;// 动物的基类 class Animal { public:Animal(string name) : _name(name) {}virtual void bark() {} …

java基础2(黑马)

一、变量里的数据在计算机中的存储原理 1.二进制 .二进制&#xff1a;只有0、1&#xff0c; 按照逢二进一的方式表示数据。 十进制数字11转换为&#xff1a;1011 方法&#xff1a;除二取余法 计算机中表示数据的最小单元&#xff0c;一个字节&#xff08;Byte&#xff0c;简…

【算法篇】贪心算法

目录 贪心算法 贪心算法实际应用 一&#xff0c;零钱找回问题 二&#xff0c;活动选择问题 三&#xff0c;分数背包问题 将数组和减半的最小操作次数 最大数 贪心算法 贪心算法&#xff0c;是一种在每一步选择中都采取当前状态下的最优策略&#xff0c;期望得到全局最优…

数据结构与算法学习笔记----博弈论

# 数据结构与算法学习笔记----博弈论 author: 明月清了个风 first publish time: 2025.2.6 ps⭐️包含了博弈论中的两种问题Nim游戏和SG函数&#xff0c;一共四道例题&#xff0c;给出了具体公式的证明过程。 Acwing 891. Nim游戏 [原题链接](891. Nim游戏 - AcWing题库) 给…

Yageo国巨的RC系列0402封装1%电阻库来了

工作使用Cadence多年&#xff0c;很多时候麻烦的就是整理BOM&#xff0c;因为设计原理图的时候图省事&#xff0c;可能只修改value值和封装。 但是厂家&#xff0c;规格型号&#xff0c;物料描述等属性需要在最后的时候一行一行的修改&#xff0c;繁琐又容易出错&#xff0c;过…

app专项测试(网络测试流程)

一、网络测试的一般流程 step1&#xff1a;首先要考虑网络正常的情况 ① 各个模块的功能正常可用 ② 页面元素/数据显示正常 step2&#xff1a;其次要考虑无网络的情况 ① APP各个功能在无网络情况下是否可用 ② APP各个页面之间切换是否正常 ③ 发送网络请求时是…

RFID隧道机:提升生产流水线效率与精准度

在当今制造业飞速发展的时代&#xff0c;生产流水线的效率与精准度成为企业竞争力的关键。传统的货物管理往往依赖于人工扫描和记录&#xff0c;效率低下且易出错&#xff0c;而RFID 隧道机的出现&#xff0c;为企业带来了智能化的管理体验&#xff0c;为生产流水线带来了从人工…