[C++] string类的介绍与构造的模拟实现,进来看吧,里面有空调

在这里插入图片描述

文章目录

  • 1、string类的出现
    • 1.1 C语言中的字符串
  • 2、标准库中的string类
    • 2.1 string类
  • 3、string类的常见接口说明及模拟实现
    • 3.1 string的常见构造
    • 3.2 string的构造函数
    • 3.3 string的拷贝构造
    • 3.4 string的赋值构造
  • 4、完整代码

1、string类的出现

1.1 C语言中的字符串

C语言中,字符串是以’\0’结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列的库函数,但是这些库函数与字符串是分离开的,不太符合面向对象的思想,而且底层空间需要用户自己管理,稍不留神可能还会越界访问。
因此C++中,为了让我们更简单、方便、快捷的使用字符串类型,C++提供了string类。

2、标准库中的string类

2.1 string类

string类文档介绍
string类在使用的时候我们需要包含头文件 #include ,以及using namespace std;

  1. 字符串是表示字符序列的类。
  2. 标准的字符串类提供了对此类对象的支持,其接口类似于标准字符容器的接口,但添加了专门用于操作单字节字符字符串的设计特性。
  3. string类是使用char(即作为它的字符类型,使用它的默认char_traits和分配器类型(关于模板的更多信息,请参阅basic_string)。
  4. string类是basic_string模板类的一个实例,它使用char来实例化basic_string模板类,并用char_traits和allocator作为basic_string的默认参数(根于更多的模板信息请参考basic_string)。
  5. 注意,这个类独立于所使用的编码来处理字节:如果用来处理多字节或变长字符(如UTF-8)的序列,这个类的所有成员(如长度或大小)以及它的迭代器,将仍然按照字节(而不是实际编码的字符)来操作。

总结:
1. string是表示字符串的字符串类。
2. 该类的接口与常规容器的接口基本相同,再添加了一些专门用来操作string的常规操作。
3. string在底层实际是:basic_string模板类的别名,
typedef basic_string<char, char_traits, allocator>string;
4. 不能操作多字节或者变长字符的序列。

3、string类的常见接口说明及模拟实现

3.1 string的常见构造

(constructor)函数名称功能说明
string()构造空的string类对象,即空字符串
string(const char* s)用C-string来构造string类对象
string(size_t n, char c)string类对象中包含n个字符c
string(const string&s)拷贝构造函数
int main()
{string s1; // 构造空的string类对象s1string s2("hello"); // 用C格式字符串构造string类对象s2string s3(s2); // 拷贝构造s3return 0;
}

3.2 string的构造函数

namespace s
{class string{public://string()//	:_str(new char[1]{ '\0' })//这里开一个空间,并赋值为\0,如果直接赋值为nullptr的话//	,_size(0)				  //在实例化一个无参对象后,对对象进行操作的时候会引发空指针异常//	,_capacity(0)//{}//全缺省构造函数string(const char* str = "")//常量字符串默认以\0结尾,因此不需要给: _size(strlen(str)), _capacity(_size){_str = new char[_capacity + 1];//多开一个空间,需要存放\0strcpy(_str, str);//将字符串拷贝到_str}private:char* _str;size_t _size;//有效存储字符个数size_t _capacity;//实际空间};
}

这里我们用一个全缺省将无参构造与构造都包括了。
这个构造函数很简单,这里就不多讲了,大家应该可以看懂。

3.3 string的拷贝构造

传统写法:

//拷贝构造
string(const string& s): _size(strlen(s._str)), _capacity(_size)
{_str = new char[_capacity + 1];strcpy(_str, s._str);
}

现代写法:

void swap(string& s)
{std::swap(_str, s._str);std::swap(_size, s._size);std::swap(_capacity, s._capacity);
}
//现代写法 s1(s2)
string(const string& s):_str(nullptr),_size(0),_capacity(0)
{string tmp(s._str);//构造swap(tmp);//this->swap(s);
}

库里提供了交换函数,我们封装一个交换函数,内部的实现就使用库里面的swap,我们拷贝构造函数里面先调用构造函数,实例化一个tmp,再将tmp与this交换。

3.4 string的赋值构造

传统写法:

string& operator=(const string& s)
{if (this != &s){string tmp(s);//拷贝构造swap(tmp);}return *this;
}

现代写法:这里与拷贝构造的现代写法是类似的,不再多说。

void swap(string& s)
{std::swap(_str, s._str);std::swap(_size, s._size);std::swap(_capacity, s._capacity);
}
string& operator=(const string& s)
{if (this != &s){string tmp(s);//拷贝构造swap(tmp);}return *this;
}

我们其实可以对现代写法继续精简一下,我们这里参数是引用传参,我们不用引用就会产生一次拷贝,对拷贝的形参直接进行交换,这样就可以简化写法,但是这里的效率其实是一样的,都是一次拷贝构造 + 一次交换。

// 极致写法,效率与上面一样
string& operator=(string tmp)//参数直接调用拷贝构造
{swap(tmp);return *this;
}

4、完整代码

#include <string.h>
#include <algorithm>
using namespace std;namespace s
{class string{public://string()//	:_str(new char[1]{ '\0' })//这里开一个空间,并赋值为\0,如果直接赋值为nullptr的话//	,_size(0)				  //在实例化一个无参对象后,对对象进行操作的时候会引发空指针异常//	,_capacity(0)//{}//全缺省构造函数string(const char* str = "")//常量字符串默认以\0结尾,因此不需要给:_size(strlen(str)),_capacity(_size){_str = new char[_capacity + 1];//多开一个空间,需要存放\0strcpy(_str, str);//将字符串拷贝到_str}//拷贝构造// 传统写法//string(const string& s)//	:_size(s._size)//	,_capacity(s._capacity)//{//	_str = new char[s._capacity + 1];//	strcpy(_str, s._str);//}void swap(string& s){std::swap(_str, s._str);std::swap(_size, s._size);std::swap(_capacity, s._capacity);}//现代写法 s1(s2)string(const string& s):_str(nullptr),_size(0),_capacity(0){string tmp(s._str);//构造swap(tmp);//this->swap(s);}//赋值// 传统写法//string& operator=(const string& s)//{//	if (this != &s)//	{//		char* tmp = new char[s._capacity];//		strcpy(tmp, s._str);//		delete[] _str;//		_str = tmp;//将tmp字符串直接给_str,类似浅拷贝//		_size = s._size;//		_capacity = s._capacity;//	}//	return *this;//}//现代写法//string& operator=(const string& s)//{//	if (this != &s)//	{//		string tmp(s);//拷贝构造//		swap(tmp);//	}//	return *this;//}// 极致写法,效率与上面一样string& operator=(string tmp)//参数直接调用拷贝构造{swap(tmp);return *this;}~string(){cout << "~string()" << endl;delete[] _str;_size = _capacity = 0;}private:char* _str;size_t _size;//有效存储字符个数size_t _capacity;//实际空间};
}

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

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

相关文章

「Qt」文件读写操作

0、引言 我们知道 C 和 C 都提供了文件读写的类库&#xff0c;不过 Qt 也有一套自己的文件读写操作&#xff1b;本文主要介绍 Qt 中进行文件读写操作的类 —— QFile。 1、QFileDialog 文件对话框 一般的桌面应用程序&#xff0c;当我们想要打开一个文件时&#xff0c;通常会弹…

php+echarts实现数据可视化实例

效果&#xff1a; 代码&#xff1a; php <?php include(includes/session.inc); include(includes/SQL_CommonFunctions.inc); ?> <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv&quo…

OpenLayers入门,OpenLayers加载google街景地图

专栏目录: OpenLayers入门教程汇总目录 前言 本章讲解OpenLayers加载google街景地图,无需科学上网,也可以正常访问瓦片。 二、依赖和使用 "ol": "^6.15.1"使用npm安装依赖npm install ol@6.15.1使用Yarn安装依赖yarn add olvue中如何使用: vue项…

FastApi-1-结合sql 增/查demo

目录 FastAPI学习记录项目结构部分接口/代码展示感受全部代码 FastAPI学习记录 fastapi已经学习有一段时间&#xff0c;今天抽时间简单整理下。 官网介绍&#xff1a; FastAPI 是一个用于构建 API 的现代、快速&#xff08;高性能&#xff09;的 web 框架&#xff0c;使用 Py…

SpringBoot的配置文件以及日志设置

在使用SpringBoot开发的过程中我们通常会用到配置文件来设置配置信息 以及使用日志来进行记录我们的操作&#xff0c;方便我们对错误的定位 配置文件的作用在于&#xff1a;设置端口&#xff0c;设置数据库连接信息&#xff0c;设置日志等等 在SpringBoot中&#xff0c;配置…

Linux系统编程:通过System V共享内存实现进程间通信

目录 一. 共享内存实现进程间通信的原理 二. 共享内存相关函数 2.1 共享内存的获取 shmget / ftok 2.2 共享内存与进程地址空间相关联 shmat 2.3 取消共享内存与进程地址空间的关联 shmdt 2.4 删除共享内存 shmctl 2.5 通信双方创建共享内存代码 三. 共享内存实现进程间…

承接各种设计

小弟985研究生毕业&#xff0c;目前攻读读博士&#xff0c;可做各种设计&#xff0c;包括但不限于Matlab 电力电子/电气工程&#xff0c;matlab/simulink 电气专业仿真MATLAB 电气工程专业&#xff0c;matlab建模 电力电子&#xff0c;电气工程&#xff0c;电力系统&#xff0c…

vue echarts macd指标 完整代码

1 逻辑 给指定的series两个对象 两个对象有相同的xAxisIndex: 2,yAxisIndex: 2, 不同的data {name: "",type: "line",data: data1,xAxisIndex: 2,yAxisIndex: 2,},{name: "",type: "bar",data: data2,xAxisIndex: 2,yAxisIndex: 2,},…

Mac M2 Pro安装使用Cocoapods

Mac Pro M2安装使用Cocoapods 在新公司要做iOS开发&#xff0c;所以在新电脑上安装Cocoapods 在升级gem&#xff0c;sudo gem update --system&#xff0c;和安装cocoapods时都遇到如下的提示&#xff1a; ERROR: While executing gem ... (Errno::EPERM)Operation not per…

Linux下安装nodejs

1、下载nodejs 点击前往&#xff1a;Download | Node.js 2、解压 tar -xvf node-v18.16.0-linux-x64.tar.xz mv node-v18.16.0-linux-x64/ /usr/local/nodejs 3、 建立软链接 此时的bin文件夹中已经存在node以及npm&#xff0c;如果你进入到对应文件的中执行命令行一点问题…

现代C++:使用 shared_from_this 防止 this 提前被释放

首先概括一下shared_from_this的作用&#xff1a;可以在类的成员函数中直接通过this得到指向当前所在对象的shared_ptr的智能指针&#xff0c;具体操作如下。 使用方法 设需要提供shared_from_this方法的类为C0定义为类&#xff0c;首先需要将C0定义为 std::enable_shared_fr…

mysql 02 数据库的约束

为防止错误的数据被插入到数据表&#xff0c;MySQL中定义了一些维护数据库完整性的规则&#xff1b;这些规则常称为表的约束。常见约束如下&#xff1a; 主键约束 主键约束即primary key用于唯一的标识表中的每一行。被标识为主键的数据在表中是唯一的且其值不能为空。这点类似…

前后端分离------后端创建笔记(10)用户修改

本文章转载于【SpringBootVue】全网最简单但实用的前后端分离项目实战笔记 - 前端_大菜007的博客-CSDN博客 仅用于学习和讨论&#xff0c;如有侵权请联系 源码&#xff1a;https://gitee.com/green_vegetables/x-admin-project.git 素材&#xff1a;https://pan.baidu.com/s/…

Spring Boot实现第一次启动时自动初始化数据库流程详解

随着互联网的发展项目中的业务功能越来越复杂&#xff0c;有一些基础服务我们不可避免的会去调用一些第三方的接口或者公司内其他项目中提供的服务&#xff0c;但是远程服务的健壮性和网络稳定性都是不可控因素。 在测试阶段可能没有什么异常情况&#xff0c;但上线后可能会出…

设计HTML5文本

网页文本内容丰富、形式多样&#xff0c;通过不同的版式显示在页面中&#xff0c;为用户提供最直接、最丰富的信息。HTML5新增了很多文本标签&#xff0c;它们都有特殊的语义&#xff0c;正确使用这些标签&#xff0c;可以让网页文本更严谨、更符合语义。 1、通用文本 1.1、标…

算法竞赛备赛之搜索与图论训练提升,暑期集训营培训

目录 1.DFS和BFS 1.1.DFS深度优先搜索 1.2.BFS广度优先搜索 2.树与图的遍历&#xff1a;拓扑排序 3.最短路 3.1.迪杰斯特拉算法 3.2.贝尔曼算法 3.3.SPFA算法 3.4.多源汇最短路Floy算法 4.最小生成树 4.1.普利姆算法 4.2.克鲁斯卡尔算法 5.二分图&#xff1a;染色法…

7. CSS(四)

目录 一、浮动 &#xff08;一&#xff09;传统网页布局的三种方式 &#xff08;二&#xff09;标准流&#xff08;普通流/文档流&#xff09; &#xff08;三&#xff09;为什么需要浮动&#xff1f; &#xff08;四&#xff09;什么是浮动 &#xff08;五&#xff09;浮…

OpenAI全球招外包大军,手把手训练ChatGPT取代码农 ; 码农:我自己「杀」自己

目录 前言 OpenAI招了一千多名外包人员&#xff0c;训练AI学会像人类一样一步步思考。如果ChatGPT「学成归来」&#xff0c;码农恐怕真的危了&#xff1f; 码农真的危了&#xff01; 当时OpenAI也说&#xff0c;ChatGPT最合适的定位&#xff0c;应该是编码辅助工具。 用Cha…

计算机竞赛 opencv 图像识别 指纹识别 - python

0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 基于机器视觉的指纹识别系统 &#x1f947;学长这里给一个题目综合评分(每项满分5分) 难度系数&#xff1a;3分工作量&#xff1a;3分创新点&#xff1a;4分 该项目较为新颖&#xff0c;适…

Vue引入Echarts报错 import * as echarts from “echarts“;

项目场景&#xff1a; 已经下载好echarts cnpm i echarts Vue引入Echarts import echarts from echarts mounted() {this.myChart echarts.init(document.querySelector(.right))this.myChart.setOption({title: {text: 消费列表,left: center},...问题描述 原因分析&#…