【C++初阶】9. string类的模拟实现

news2024/11/23 19:31:30

string类的完整实现放这里啦!快来看看吧

1. string类的成员

string类的作用就是将字符串类型实现更多功能,运算符重载,增删改查等等操作,所以其成员就包含char*的字符串

private:
		char* _str;
		size_t _capacity;
		size_t _size;

2. 构造函数

2.1 带参构造函数

在之前的学习过程中,我们了解到类中存在的六个默认函数,其中就包含默认构造函数,那么对于string类是否需要用户自己实现构造函数呢?
答案是需要的,我们需要根据字符串的长度开辟空间,也需要将字符串拷贝到开辟的空间当中

		// 带参的构造函数
		string(const char* str)
		{
			_capacity = strlen(str);
			_size = _capacity;
			_str = new char[_capacity + 1];

			strcpy(_str, str);
		}

我们的代码实现中_capacity是计算到’\0’停止,所以在堆上new的时候要加1,给’\0’预留空间

2.2 不带参构造函数

		string()
		{
			_str = new char[1];
			_str[0] = '\0';
			_capacity = _size = 0;
		}

不带参数就开辟1个字节的空间存放\0

2.3 默认缺省构造函数

		string(const char* str = "")
		{
			_capacity = strlen(str);
			_size = _capacity;
			_str = new char[_capacity + 1];

			strcpy(_str, str);
		}

对于不传参的string类初始化,则是采用默认值的方式"" 该字符串自带斜杠0

这里需要区分清楚:‘\0’ / “\0” / “” 这几种情况的区别:

  • '\0’是字符\0 ASCII码值为0 相当于nullptr 拿nullptr作为默认值,后面strlen直接报错
  • 而"\0" 则是用两个\0初始化字符串
  • ""就是单纯的\0

3. 拷贝构造函数

那么拷贝构造是否也需要用户实现呢?
答案是需要的,因为string类的构造会开辟新空间,那么要实现对空间的深拷贝就需要自己实现

		// 深拷贝
		string(const string& s)
		{
			_capacity = s._size;
			_size = _capacity;
			_str = new char[_capacity + 1];

			strcpy(_str, s._str);
		}

4. 赋值重载函数

// s1 = s3;
string& operator=(const string& s)
{
	if (this != &s)
	{
		char* tmp = new char[s._capacity + 1];
		strcpy(tmp, s._str);

		delete[] _str;
		_str = tmp;

		_size = s._size;
		_capacity = s._capacity;
	}
	return *this;
}

首先要判断f赋值符号左右两边是否是同一对象,是则直接返回*this,否则再进一步操作

拓展:现代写法的拷贝构造和赋值重载

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

5. 析构函数

~string()
		{
			delete[] _str;
			_str = nullptr;
			_size = _capacity = 0;
		}

6. c_str()

const char* c_str() const
		{
			return _str;
		}		

c_str 返回的是string类中的字符串数组的地址,对于流插入(<<) 会自动识别类型,const char* 类型会以字符串的形式打印输出%s
所以,string类通常用该接口打印字符串

7. size()

		size_t size() const
		{
			return _size;
		}

返回当前字符串长度(不包含\0) 最好设计成size_t 类型:因为size不会出现负数的情况

8. capacity()

size_t capacity() const
{
	return _capacity;
}

返回当前字符串容量

9. operator[]

		// 普通对象:可读可写
		char& operator[](size_t pos)
		{
			assert(pos < _size);
			return _str[pos];
		}

		// const对象:只读
		const char& operator[](size_t pos) const
		{
			assert(pos < _size);
			return _str[pos];
		}

对[]的重载,[]访问分为两种情况:普通对象(可修改数据)const对象(不可修改)
传引用返回更加高效,也可修改数据
记得assert断言,防止出现越界访问的情况

10. 迭代器的实现

迭代器的底层可能是指针,也可能不是(list等其他结构),在string类中迭代器的底层就是char* 类型的指针

		typedef char* iterator;

		iterator begin()
		{
			return _str;
		}

		iterator end()
		{
			return _str + _size;
		}

范围for循环的本质就是迭代器 范围for自动替换成迭代器中的begin和end,如果把begin替换成Begin也无法配对(报错)
在这里插入图片描述

11. reserve() – 调整字符串容量(扩容)

当我们要进行增删改查等操作时,如果空间过小则无法继续进行,需要扩容

		void reserve(size_t n)
		{
			if (n > _capacity)
			{
				char* tmp = new char[n + 1];
				strcpy(tmp, _str);
				delete[] _str;
				_str = tmp;

				_capacity = n;
			}
		}

实现接口的方式就是在堆上重新找一块n大小的空间,将原空间拷贝过来并释放原空间
将_str指向新空间,将_capacity置为n

12. 尾插单个字符

		void push_back(char ch)
		{
			if (_size == _capacity)
			{
				size_t newCapacity = _capacity == 0 ? 4 : _capacity * 2;
				reserve(newCapacity);
			}

			_str[_size] = ch;
			++_size;
			_str[_size] = '\0';
		}
		
		string& operator+=(char ch)
		{
			push_back(ch);
			return *this;
		}

在尾插单个字符的时候要注意,之前_size位置的元素是\0,所以在_size++之后要在将_size放入\0

13. 尾插字符串

		void append(const char* str)
		{
			size_t len = strlen(str);
			if (_size + len > _capacity)
			{
				reserve(_size + len);
			}
			strcpy(_str + _size, str);
			_size += len;
		}
			
		string& operator+=(const char* str)
		{
			append(str);
			return *this;
		}

而尾插字符串时因为str自带\0,strcpy会拷贝\0,所以_size+_len 位置就是\0,不需要单独处理

14. 在任意位置插入单个字符

在这里插入图片描述

		string& insert(size_t pos,char ch)
		{
			assert(pos <= _size);
			if (_capacity == _size)
			{
				size_t newCapacity = _capacity == 0 ? 4 : _capacity * 2;
				reserve(newCapacity);
			}

			size_t end = _size + 1;
			while (end > pos)
			{
				_str[end] = _str[end - 1];
				--end;
			}

			_str[pos] = ch;
			++_size;

			return *this;
		}

15. 在任意位置插入字符串

在这里插入图片描述

16. 删除len个字符

在这里插入图片描述

17. 查找字符/子串

在这里插入图片描述

18. 调整大小

在这里插入图片描述

19. 流插入、流提取

在之前的学习过程中,我们了解到流提取和流插入一般都不会实现成成员函数,因为istream / ostream 会抢占this指针的位置
提问:是不是流提取和流插入一定要实现成友元全局函数呢?
答:不是,全局函数是正确的(不能定义在类体内) 但是不一定要实现成友元,友元的作用是帮助我们去访问类内的成员。
在这里插入图片描述
流提取和流插入是为自定义类型而生的(C++),printf和scanf对内置类型非常友好但是无法识别自定义类型(C语言)
在这里插入图片描述
所以在打印string类时还是推荐使用流插入
在这里插入图片描述
经过get函数的优化已经可以基本实现流提取功能,但是针对众多字符的插入采用+=操作会导致频繁扩容的情况,那么如何优化呢?

优化1:临时空间减少扩容

在这里插入图片描述

优化2:覆盖数据

在这里插入图片描述
到这里string类就完整实现啦!撒花✿✿ヽ(°▽°)ノ✿

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

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

相关文章

三对角矩阵原理及C++实现

一、三对角矩阵 1.三对角矩阵概念 2.三对角矩阵元素数量 对于给定n阶方阵M&#xff0c;若其为三对角矩阵&#xff0c;则元素个数N为&#xff1a; 若n1&#xff0c;此时方阵只有一个元素M[0][0]&#xff0c;由定义知该元素也在三对角线上。故N1。若n>1&#xff0c;由三对角…

chatgpt赋能python:Python文件夹的使用和优化

Python 文件夹的使用和优化 文件夹是计算机操作系统中最基本的存储单位之一。在计算机领域&#xff0c;文件夹也被称为目录。文件夹中可以存储多个文件或其他文件夹&#xff0c;使得文件在计算机中可以更好的组织和管理。基于Python语言&#xff0c;我们可以很容易地创建、读取…

javaEE基于springboot的小区社区文化活动报名系统jsp生活服务网站

社区文化宣传网站采用的开发框架为springboot框架&#xff0c;开发工具采用Eclipse&#xff0c;idea 服务器用的是Tomcat。编码语言是Java&#xff0c;数据库采用Mysql数据库。 本社区文化宣传网站&#xff0c;主要服务的用户是社区附近的居民&#xff0c;为居民展示最新的新闻…

带电更换10kV架空线路直线杆绝缘子(绝缘手套作业法)

一、现场复勘 1.核对线路及杆塔号 线路双重名称及杆号无误。 2.检查杆身质量 3.检查电杆埋深 4.检查拉线受力情况 5.检查相邻杆情况 作业点及相邻侧电杆之间导线应无断股等现象。 6.检查气象条件 作业前需进行湿度和风速的测量&#xff0c;风力大于5级&#xff0c;或湿度大…

5分钟搞定验证码

验证码生成 本效果是利用easy-captcha工具包实现&#xff0c;首先需要添加相关依赖到pom.xml中&#xff0c;代码如下&#xff1a; <dependency><groupId>com.github.whvcse</groupId><artifactId>easy-captcha</artifactId><version>1.6…

链式二叉树高质量OJ—【Leedcode】

目录 ​编辑 1. 单值二叉树 题目 题目分析 代码实现 不带返回值版本 带返回值版本 递归展开图 2. 相同的树 题目 题目分析 代码实现 3. 对称二叉树 题目 题目分析 代码实现 4. 另外一颗子树 题目 题目分析 代码实现 递归展开图 5. 二叉树的前、中、后序遍…

给电脑重装系统有什么坏处吗

电脑重装系统是解决一些问题的常见方法&#xff0c;但是它也存在一些潜在的坏处。本文将为您详细介绍电脑重装系统的坏处&#xff0c;并提供一些注意事项&#xff0c;帮助您做出明智的决策。 工具/原料&#xff1a; 系统版本&#xff1a;Windows10 品牌型号&#xff1a;惠普…

涂鸦智能发布全球首款Matter+Alexa Built-in涂鸦智选智慧中控屏L

根据Parks Associates今年4月发布的《Next-Generation Smart Home: Building for the Future》显示&#xff0c;41%的美国互联网家庭拥有智能家居设备&#xff0c;越来越多的家庭正在部署全屋智能。 当家中出现越来越多的智能设备时&#xff0c;智慧中控屏&#xff0c;凭借“所…

行业报告 | AIGC应用与实践展望报告:人工智能重塑内容产业的作业模式

原创 | 文 BFT机器人 前言 Introduction 不可否认AIGC的出现似乎已经让大家预见了Al应用的拐点&#xff0c;其创造性与智能性一夜之间刷新了大众认知。但去伪存真&#xff0c;在市场火爆的背后其真正的应用及商业价值几何&#xff0c;更待我们冷静地剖析。 01 概念重生&#…

破解excel单元格保护

EI目录.xlsx 被保护&#xff0c;想查其中期刊&#xff0c;却不能直接复制。 step1.文件后缀改成.rarstep2.360压缩包打开&#xff0c;找到【sheet1.xml】step3.使用记事本打开&#xff0c;删除部分指定代码step4.后缀改回.xlsx 我是用360压缩包可以直接在.rar中 进行修改。 …

生态环境监测好帮手——便携式水污染物监测设备

便携式水污染物监测设备也可以称作便携式水质多参数检测仪 根据生态环境保护需要而专门研发的一款可快速准确测定地表水、地下水、城市污水及工业废水中CODcr、氨氮、总磷、总氮等50余种指标&#xff0c;浓度直读&#xff1b;可广泛用于水厂、食品、化工、冶金、环保及制药行业…

《机器人SLAM导航核心技术与实战》第1季:第5章_机器人主机

视频讲解 【第1季】5.第5章_机器人主机-视频讲解 【第1季】5.1.第5章_机器人主机_X86与ARM主机对比-视频讲解 【第1季】5.2.第5章_机器人主机_ARM主机树莓派3B-视频讲解 【第1季】5.3.第5章_机器人主机_ARM主机RK3399-视频讲解 【第1季】5.4.第5章_机器人主机_ARM主机Jetso…

chatgpt赋能python:Python文件大小函数:了解文件大小的方法和掌握文件操作技巧

Python文件大小函数&#xff1a;了解文件大小的方法和掌握文件操作技巧 文件大小是我们经常需要考虑的一个问题&#xff0c;无论是在计算机存储、文件上传、程序优化等场景中都需要关注。在Python中&#xff0c;我们可以通过文件操作函数来查询文件大小&#xff0c;这篇文章将…

看了两位阿里P10的成长经历,我的认知升华了

两位 P10 大佬的成长经历 相信不少人和我一样&#xff0c;对这些高段位大佬的成长经历有很强的好奇心&#xff0c;想知道他们是如何达到这一步的&#xff0c;这期间有什么关键的选择。这一节我们来看下他们的成长经历&#xff0c;通过了解前辈是如何成长的&#xff0c;可以帮助…

Oracle11G安装说明

Oracle11G安装说明 一、序二、安装安装依赖包基础环境配置安装Oracle 三、配置Oracle 一、序 Oracle和MySQL语法区别&#xff1a;https://blog.csdn.net/lanmuhhh2015/article/details/97763615 Oracle创建用户、角色、授权、建表&#xff1a;https://www.cnblogs.com/roger1…

chatgpt赋能python:Python散点图的颜色设置

Python散点图的颜色设置 什么是散点图&#xff1f; 散点图是一种数据可视化的图表类型。它用于观察两个变量之间的关系。通常&#xff0c;x轴表示一个变量&#xff0c;y轴表示另一个变量。每个点表示一个数据点&#xff0c;它在x和y轴上分别具有对应的值。我们可以通过比较散…

再获数千万元追加投资!宏景智驾B轮总融资已近「5亿元」

5月26日&#xff0c;宏景智驾&#xff08;Hyperview&#xff09;宣布获得阿美风险投资&#xff08;Aramco Ventures&#xff09;旗下多元化成长基金Prosperity7 Ventures数千万元的追加投资&#xff0c;这也是继2022年2月Prosperity7独家投资宏景智驾超亿元战略融资后又一次投出…

博途1200PLC由丝杠位移速度计算电机转速(moveVel_TO_motorSpeed功能块)

博途PLC 脉冲轴控制,功能块介绍请参看下面文章博客,这篇博客介绍实际组态、编程时的注意事项,仅供参考,受水平和能力所限文中难免有错误和不足之处,欢迎大家评论指出。 博途1200PLC轴控功能块(脉冲轴)_西门子1200可以总线控制伺服么_RXXW_Dor的博客-CSDN博客STRUCT// 轴使…

查询物流不再困难——教您一招批量查询物流信息很管用

在物流行业&#xff0c;快递批量查询高手是一款必备工具。这款软件如同瑞士军刀一样&#xff0c;可以解决许多查询和管理工作中的难题。让我们一起来探讨一下快递批量查询高手的背景、需求、实现方案、功能特点以及应用案例&#xff0c;以了解它的重要性以及实用性。 首先&…

chatgpt赋能python:Python文件所在目录

Python文件所在目录 什么是Python文件所在目录&#xff1f; 在Python编程中&#xff0c;文件所在目录指的是存储Python代码文件的文件夹。该文件夹包含所有Python代码文件&#xff0c;这些文件可以包含函数、类、变量等。 如何查找Python文件所在目录&#xff1f; Python文…