C++STL-string类的实现(上)

news2024/10/6 16:24:41

在上一篇中,我们知道了string类的一些基本使用,这一篇我们就说一下string类的具体的底层实现。
在这里插入图片描述

文章目录

  • 1.预前准备
    • 1.1 初步的构造和析构
    • 1.2 下标的运算符重载
  • 2. 深浅拷贝
    • 2.1 拷贝构造函数
    • 2.2 =运算符重载
  • 3. 完善前面写的函数
    • 3.1 完善构造函数和析构函数
    • 3.2 完善拷贝构造函数
    • 3.3 完善下标运算符和赋值运算符重载
    • 3.4 返回有效字符大小和空间的函数
  • 4. 增加的函数
    • 4.1 reserve函数
    • 4.2 push_back函数
    • 4.3 append函数
    • 4.4 operator+=函数
    • 4.5 resize函数
    • 4.6 insert函数
      • 4.6.1 插入一个字符
      • 4.6.2 插入一个字符串
      • 4.6.3 插入一个string类对象
    • 4.7 earse函数
  • 5. 一些比较函数
  • 6. find函数
    • 6.1 查找一个字符
    • 6.2 查找一个字符串

1.预前准备

首先,我们在string.h文件里面定义一个my_string命名空间域。
在这里插入图片描述
在里面实现一些最简单,最基本的内容。

1.1 初步的构造和析构

在这里插入图片描述

1.2 下标的运算符重载

这个函数比较简单,我们来看代码:
在这里插入图片描述
这里的返回值是引用,那么主要的作用就是为了可以达到修改的效果。
为了方便验证,我们再写两个函数:
在这里插入图片描述
因为我们没有写流插入和流提取的重载,但我们可以用这个获取等效的 C 字符串来打印。
在这里插入图片描述
从这里,我们可以看到进行修改了。准备工作做好了,就开始新的内容。

2. 深浅拷贝

2.1 拷贝构造函数

在编译器中,如果我们没有自己写拷贝构造那么编译器自己会默认生成一个拷贝构造函数。而默认生成的拷贝构造是浅拷贝也就是值拷贝
我们来看下面的代码:
在这里插入图片描述
从这里,我们可以看到程序崩溃了。为什么呢?
首先,这个程序的内存图是这样的:
在这里插入图片描述
在这里插入图片描述
从这里我们也可以清楚看见确实是值拷贝。为什么会程序崩溃有两点。
1.首先析构会析构两次。2.如果修改某一个另外一个也会被修改。

那么对这个问题,我们只能去写深拷贝:
在这里插入图片描述
在这里插入图片描述
从检验中,我们也可以看出程序没有崩溃,也没有一起被改变。

2.2 =运算符重载

赋值运算符重载和拷贝构造是一样的问题。
在这里插入图片描述
如果直接赋值就是把值复制过去,那么也会出现上面发生的问题。
我们也需要自己去写深拷贝:
在这里插入图片描述
在这里插入图片描述
从这里,我们可以看到并没有什么错误了。
但是这个代码还有一点问题:如果我们自己给自己赋值。
在这里插入图片描述
你会发现它出现乱码了。原因是这样的:
在这里插入图片描述
因为在这里,我们把s1的空间给先直接释放掉了,然后我们又给它开辟了s1相同大的空间,但前面我们给释放掉了,里面就是随机值,随机值会找到’\0’才结束,所以里面是乱码。
如果自己给自己赋值,我们需要判断一下:
在这里插入图片描述
但这样写,还有点瑕疵。就是如果new开辟失败了,那么s1自己也被销毁了。这样是不好的,如果开辟失败,s1也不会销毁才是好的。
在这里插入图片描述

3. 完善前面写的函数

3.1 完善构造函数和析构函数

在这里插入图片描述
在这里插入图片描述
增加这两个的目的就是为了可以增删查改。我们这里并没有算’\0’,计算的是有效的字符个数。
但我们还没有写这样的一个创建方式:
在这里插入图片描述
这样写我们没有给参数,默认的是一个空字符串,我们需要写一个全缺省的默认构造函数。
在这里插入图片描述
但我们可以把这两个放在一起写,成为一个全缺省的默认构造函数:
在这里插入图片描述

3.2 完善拷贝构造函数

在这里插入图片描述

3.3 完善下标运算符和赋值运算符重载

下标运算符:
在这里插入图片描述
赋值运算符:
在这里插入图片描述
但此时,下标运算符还差一个:
在这里插入图片描述
从这里,我们可以看出没有合适的下标运算符匹配。原因是:我们这里的对象s是被const修饰的,它是只能读,不能写的。而我们现在的[]运算符函数的对象是一个可读可写的。权限放大了,所以不行。我们还要再写一个:
在这里插入图片描述

3.4 返回有效字符大小和空间的函数

在这里插入图片描述

4. 增加的函数

4.1 reserve函数

在string类里面,reserve函数的意思是指定n的大小来扩容。
在这里插入图片描述
我们先开辟新的空间,然后将内容拷贝到新空间里,在销毁原来的空间,在把新空间赋给_str。

4.2 push_back函数

在string类里面,push_back函数就是插入一个字符。
在这里插入图片描述
在这里插入图片描述
从这里,我们可以看到是可以添加的,但是这里有一个bug。
在这里插入图片描述
如果,我们一开始没有开空间,那么这里就会出现崩溃,原因就是在上面的函数里,_capacity*2如果_capacity是0那么它永远都是0,所以会出现越界访问。

正确写法如下:
在这里插入图片描述

4.3 append函数

append函数在string类里面的作用是添加一个字符串或添加一个字符串对象。
在这里插入图片描述
因为在C++里面没有扩容函数,那么我们只能先算出它要添加的长度和现在长度的和,然后指定扩容到这里,然后再拷贝过来。
在这里插入图片描述
这个是追加一个对象的。

4.4 operator+=函数

这个函数就是复用push_back和append函数的。
在这里插入图片描述

4.5 resize函数

resize函数在string类里面有两部分作用:
1.扩空间+初始化。2.删除部分数据,保留前n个。
这个函数其实具有三种情况:
第一种情况:要开辟的空间n大于_capacity
在这里插入图片描述
假如,有一份空间的_capacity为15,里面已经有了hello world这11个字符。
如果我们要resize(20,‘x’),这个意思就是说要存20个有效数据。因为前面已经有了11个,我们扩容后,后面加9个x就行。
在这里插入图片描述
第二种情况:n小于_capacity,大于_size
在这里插入图片描述
如果我们要resize(14,‘x’),这里hello world已经有了11个字符,容量为15也够。所以只需要在后面添加3个x就行了。
在这里插入图片描述
第三种情况:n小于_size
在这里插入图片描述
如果我们要resize(5,‘x’),只保留有效字符前5个就行了。
在这里插入图片描述
实现的代码如下:
在这里插入图片描述

4.6 insert函数

insert函数在string类里面的意思是:在pos位置上插入。

4.6.1 插入一个字符

这个和我们在顺序表哪里是非常相似的。就是把pos位置往后的都向后移一位,然后在pos位置上插入就行了。
在这里插入图片描述
但是,这行代码还存在一些问题:
在这里插入图片描述
从这里,我们可以看出当头插时,程序崩溃。原因就是:当end为-1时,由于它是无符号类型,所以end就会成为最大整数,出现越界。
解决办法一:把end的类型和pos的size_t类型都改成int类型
在这里插入图片描述
解决办法二:将pos和end比较时,强制类型转换成int类型
在这里插入图片描述
解决办法三:将end指向’\0’后一个位置,每次是把前一个位置往后移,当end==pos结束
在这里插入图片描述

4.6.2 插入一个字符串

我们插入一个字符串,首先要扩容。然后将end指向最后一个位置,把end-len位置的数据往end位置上移。当end=pos+len-1时结束循环。
在这里插入图片描述

4.6.3 插入一个string类对象

插入一个string类对象和插入一个字符串是一样的道理。
在这里插入图片描述

4.7 earse函数

我们先来看一下标准库里面的函数:
在这里插入图片描述
这里有一个npod,它在string类里面是一个静态的成员变量。意思是:如果我们没有自己输入len就会默认len为npos,则把pos位置以后的数据全删了。现在,我们把这个静态成员变量给写上。
在这里插入图片描述
这个该怎么删除呢?有两种情况,我们来分析一下:
第一种情况:len+pos>=_size

在这里插入图片描述
像这种情况,是比较简单的,我们只需要将pos位置的值直接为’\0’就行了。
在这里插入图片描述
第二种情况:len+pos<_size
在这里插入图片描述
此时,我们需要将begin开始往后的数据,一个一个的往pos位置往后移。
在这里插入图片描述

5. 一些比较函数

在这里插入图片描述
这些函数都比较简单,但是这些函数不是写在类里面的,而是写在类外的。因为,我们这些函数不用访问类里面的私有变量,而是通过c_str函数来访问的。

6. find函数

6.1 查找一个字符

在这里插入图片描述

6.2 查找一个字符串

在这里插入图片描述

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

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

相关文章

【自用】Linux服务器部署Oracle并使用数据库管理工具Navicat远程连接(包含远程Navicat配置)

一、服务器端 配置 0.传输oracle安装包和依赖 1.更新依赖 yum update2.检测oracle依赖 rpm -ivh oracle-database-preinstall-19c-1.0-1.el7.x86_64.rpm # 请根据版本选择3.yum安装oracle-database-preinstall yum install oracle-database-preinstall-19c-1.0-1.el7.x86_6…

Azide-PEG-Cholesterol,N3-PEG-Cholesterol,叠氮-PEG-胆固醇PEG试剂供应

化学试剂胆固醇-聚乙二醇-叠氮,其英文名为Cholesterol-PEG-Azide&#xff08;Cholesterol-PEG-N3&#xff09;&#xff0c;它所属分类为DSPE PEG Azide PEG。 试剂胆固醇PEG叠氮的分子量均可定制&#xff0c;有&#xff1a;Cholesterol-PEG 2k-Azide、胆固醇-聚乙二醇 3.4k-叠…

SMBMS系统_准备工作

构建项目Maven/jar 初次构建项目时&#xff0c;思考是不是通过maven创建&#xff0c;使用maven的化需要导入那些依赖&#xff1b; 如果不是使用maven创建项目的话&#xff0c;使用哪些些jar包。 检测验证项目 选择使用maven创建项目完成&#xff0c;可以使用模板&#xff0c…

嵌入式分享合集106

一、可控硅控制电路实例 可控硅是可控硅整流器的简称。可控硅有单向、双向、可关断和光控几种类型。它具有体积小、重量轻、效率高、寿命长、控制方便等优点&#xff0c;被广泛用于可控整流、调压、逆变以及无触点开关等各种自动控制和大功率的电能转换的场合。 单向可控硅是一…

【CloudCompare教程】001:CloudCompare中文版下载与安装图文教程

CloudCompare是一款功能强大的点云后处理软件,本文讲解CloudCompare中文版下载与安装方法。 文章目录 一、CloudCompare下载地址二、CloudCompare安装教程三、CloudCompare中文设置一、CloudCompare下载地址 官方下载地址:http://www.danielgm.net/cc/release/ 二、CloudComp…

vue中使用wangeditor富文本编辑器

官方文档 项目中要求实现富文本编辑器取编辑内容 这种编辑器有好多选择了wangeditor富文本编辑器 首先根据文档安装 yarn add wangeditor/editor # 或者 npm install wangeditor/editor --saveyarn add wangeditor/editor-for-vuenext # 或者 npm install wangeditor/edit…

MySQL进阶实战8,分区表详解

目录一、分区表二、分区的作用三、分区的一些限制四、分区表的增删改查1、select2、insert3、delete4、update五、分区表的类型六、如何使用分区表七、分区表会有哪些问题&#xff1f;1、分区列和索引列不匹配2、选择分区的成本可能很高3、打开并锁住所有底层表的成本可能会很高…

统计信号处理基础 习题解答6-9

题目&#xff1a; 在开关键控&#xff08;OOK&#xff09;的通信系统中&#xff0c;我们发射两个信号中的一个&#xff0c;即 表示bit0&#xff0c;而 表示bit1。假定幅度是正的&#xff0c;为了确定发射的是哪个bit&#xff0c;我们对接收机的波形在符号周期内 进行采样&…

深入了解快速排序和归并排序

作者&#xff1a;~小明学编程 文章专栏&#xff1a;Java数据结构 格言&#xff1a;目之所及皆为回忆&#xff0c;心之所想皆为过往 快速排序和归并排序作为排序中的两个重点&#xff0c;也是面试中最常考的两个知识点&#xff0c;这里带大家详解的了解这两个排序。 目录 快速…

DSPE-PEG-TPP;磷脂-聚乙二醇-磷酸三苯酯;(阻燃剂TPP)是种含磷元素的化合物,可用作无卤环保型阻燃剂

中文名称&#xff1a; 二硬脂酰基磷脂酰乙醇胺-聚乙二醇-磷酸三苯酯&#xff1b;三苯基磷聚乙二醇磷脂 英文简称&#xff1a; DSPE-PEG-TPP,TPP-PEG-DSPE 分子量&#xff1a; 2000,3400,5000等 溶剂: 溶于部分有机溶剂 磷酸三苯酯为无味、无臭的白色结…

JDK8 连接Access数据库

JDK8 连接Access数据库1. 安装JDK82. 下载配置文件3. 源码设置前面我们讲了如何使用Java连接ODBC并配置Access数据库&#xff0c; 参考连接&#xff1a;https://jackwei.blog.csdn.net/article/details/86285822 可以知道JDK8之后已经不支持jdbc-odbc桥接了&#xff0c;如果你可…

windows10上运行magic keyboard和magic mouse

windows10上运行magic keyboard和magic mouse并保持你的mac习惯 所有需要的软件和插件都可以在这里寻找到链接&#xff1a;https://pan.baidu.com/s/1Y8vjRnznqKP7f8dFFrHoGw?pwdvpsy 提取码&#xff1a;vpsy 安装蓝牙 你的windows电脑可能自带了蓝牙&#xff0c;那你直接…

保姆级教程带你从0到1实现基于bitcask的kv存储引擎

愿景 ​ 今年大部分业余时间都在nutsdb的开源贡献上&#xff0c;nutsdb是基于bitcask模型实现的持久化存储引擎&#xff0c;提供了诸如list&#xff0c;set等多种丰富的数据结构。近来很多小伙伴&#xff0c;其中也有一些我的好朋友陆陆续续加入到这个项目上来。为了帮助小伙伴…

tensorflow2 SqueezeNet

前面学习了通过加深网络和加宽网络来改进模型质量&#xff0c;提高模型精度的深度学习backbone模型&#xff08;LeNet,VGGNet,AlexNet,GoogleNet,ResNet),这里介绍如何使网络更快&#xff0c;结构更轻量化的改进深度神经网络模型之一————SqueezeNet&#xff0c;它能够在Ima…

【JavaWeb】文件的上传和下载

文章目录一.文件的上传介绍⭐️1.文件上传及HTTP协议的说明2.commons-fileupload.jar常用API介绍说明二.文件下载⭐️一.文件的上传介绍⭐️ 1.文件上传及HTTP协议的说明 (1).要有一个form标签,methodpost请求 (2).form标签的encType属性值必须为multipart/form-data值 (3).在…

VTK在Windows上的安装

本章介绍在计算机系统上安装VTK。在Microsoft Windows上&#xff0c;可以安装预编译的vtk.exe&#xff0c;也可以从源码自行编译vtk软件。您可能希望了解系统架构&#xff0c;阅读会使编译过程更容易跟踪。如果遇到问题&#xff0c;可以联系vtkusers邮件列表。 2.1 概述 VTK在…

【HTML + CSS】笔记

页面设计 1.HTML&#xff1a;结构框架 2.CSS 3.JS HTML&#xff1a;超文本标记语言 <...>&#xff1a;标签/元素 <!DOCTYPE html>&#xff1a;解释文档类型为html head区域常用标签 <base> 使用后浏览器不再使用当前文档的URL&#xff0c;而使用指定的…

web前端设计与开发期末作品/期末大作业-疫情

Web前端开发技术 描述 网页设计题材&#xff0c;DIVCSS 布局制作,HTMLCSS网页设计期末课程大作业&#xff0c;击疫情致敬逆行者感人类题材 | 致敬逆行者网页设计作品 | 大学生抗疫感动专题网页设计作业模板 | 等网站的设计与制作 | HTML期末大学生网页设计作业 HTML&#xff1a…

Windows之应用安装程序 —— winget

大家都用过Linux中的应用程序安装工具&#xff0c;如yum、apt、rpm等工具进行安装自己想要的一些工具或则软件之类的&#xff0c;当然Linux操作系统还是很强大的有很多类似的命令来安装我们所需要的程序&#xff0c;但是windwos有没有类似于windows这样的应用安装程序呢&#x…

可解释的AI:用LIME解释扑克游戏

可解释的AI&#xff08;XAI&#xff09;一直是人们研究的一个方向&#xff0c;在这篇文章中&#xff0c;我们将看到如何使用LIME来解释一个模型是如何学习扑克规则的。在这个过程中&#xff0c;我们将介绍: 如何将LIME应用到扑克游戏中;LIME如何工作;LIME 的优点和缺点是什么。…