当前位置: 首页 > news >正文

c++系列之string的模拟实现

在这里插入图片描述

💗 💗 博客:小怡同学
💗 💗 个人简介:编程小萌新
💗 💗 如果博客对大家有用的话,请点赞关注再收藏 🌞

string()

//注意事项:
1.初始化列表随声明的顺序进行初始化
2.const char* str = nullptr 是错误写法,编译器会报错
3.const char* str = ‘\0’类型不匹配
4.capacity+1 的原因是 _capacity是有效字符的数量加一是为了给‘\0’留空间

//构造函数
string(const char* str = "")
{_size = strlen(str);_capacity = _size;_str = new char(_capacity + 1);memcpy(_str, str, _size + 1);
}

string()

//这里重点注意深浅拷贝
浅拷贝:也称位拷贝,编译器只是将对象中的值拷贝过来.(如果自己没写拷贝函数,编译器会自动生成浅拷贝的拷贝函数)
浅拷贝的两大缺陷:
1.如果对象中管理资源,最后就会导致多个对象共
享同一份资源.
2.当一个对象销毁时就会将该资源释放掉,而此时另一些对象不知道该资源已经被释放,以为
还有效,所以当继续对资源进项操作时,就会发生发生了访问违规。
在这里插入图片描述

深拷贝:如果一个类中涉及到资源的管理,其拷贝构造函数、赋值运算符重载以及析构函数必须要显式给出。一般情况都是按照深拷贝方式提供。
在这里插入图片描述

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

3.~string()

//析构函数
~string(){_size = _capacity = 0;delete[] _str;_str = nullptr;}

4. push_back()

//尾插字符
void push_back(char c)
{if (_size == _capacity){int newcapacity = _capacity == 0 ? 4 : 	_capacity * 2;reserve(newcapacity);_str[_size++] = c;_str[_size] = '\0';}
}

5.append()

//尾插字符串
void append(const char* str)
{size_t len = strlen(str);if (_size + len > _capacity){reserve(_size+len);}/*strcpy(_str+_size, str);*/memcpy(_str+_size,str,len+1);_size = _size + len;
}

6.insert()

//在pos添加字符或字符串
string& insert(size_t pos, size_t n,char c)
{assert(pos <= _size);if (_size+n > _capacity){reserve(_size+n);}size_t end = _size;while (end >= pos && end != npos){_str[end + n] = _str[end];end--;}for (int i = 0; i < n; i++){_str[pos+i] = c;}_size += n;return *this;}string& insert(size_t pos, const char* str)
{assert(pos <= _size);int len = strlen(str);if (_size + len > _capacity){reserve(_size + len);}size_t end = _size;while (end >= pos && end != npos){_str[end + len] = _str[end];end--;}for (int i = 0; i < len; i++){_str[pos + i] = str[i];}_size += len;return *this;
}

7.erase()

//消除从pos位置开始n个字符
string& erase(size_t pos, size_t len = npos)
{assert(pos < _size);if (len == npos || pos + len >= _size){_str[pos] = '\0';_size = pos;}while (pos <= _size-len){_str[pos] = _str[pos + len];pos++;}_size -= len;return *this;
}

8.find()

 返回c在string中第一次出现的位置
size_t find(char c, size_t pos = 0) const
{for (size_t i = pos; i < _size; i++){if (_str[i] == c){return i;}}} 返回子串s在string中第一次出现的位置size_t find(const char* s, size_t pos = 0) const
{char* str = _str + pos;while (*str){const char* scopy = s;const char* strcopy = str;while (*scopy && *scopy == *strcopy){scopy++;strcopy++;	}if (*scopy == '\0'){return str - _str;}else{str++;}}
return npos;
}

9.clear()

//清理字符
void clear()
{_size = 0;_str[0] ='\0';
}

10.size()

//返回有效字符大小
//这里const 是为了能让const对象和非const对象都能够调用
size_t size() const
{return _size;
}

11.c_str()

//返回字符串
//这里const 是为了能让const对象和非const对象都能够调用
const char* c_str() const
{return _str;
}

12.capacity()

//返回有效容量大小
//这里const 是为了能让const对象和非const对象都能够调用
size_t capacity() const
{return _capacity;
}

13. operator<

bool operator<(const string& s)const
{int ret = memcmp(_str, s._str, _size < s._size ? _size : s._size);return ret == 0 ? _size < s._size : ret < 0;	
}

14.operator==

bool operator==(const string& s))const
{return s._size == _size && memcmp(_str, s._str, _size ) == 0;
}

15.operator<=

bool operator<=(const string& s)const
{return *this < s &&  *this == s;
}

16.operator>

bool operator>(const string& s)const
{return !(*this <= s);
}

17.operator>=

bool operator>=(const string& s)const
{return !(*this < s);
}

18.operator!=

bool operator!=(const string& s)
{return !(*this == s);
}

19.operator[]

//可读可改
char& operator[](size_t index)
{assert(index < _size);return _str[index];
}
//只读不改
const char& operator[](size_t index)const;
{assert(index < _size);return _str[index];
}

20.operator=

string& operator=(string s)//这里调用拷贝构造,不改变原对象
{if (this != &s){std::swap(_size, s._size);std::swap(_capacity, s._capacity);std::swap(_str, s._str);}return *this;
}string& operator=(const string& s)
{if (&s != this){string tmp(s);std::swap(_size, tmp._size);std::swap(_capacity, tmp._capacity);std::swap(_str, tmp._str);}
return *this;
}

21.operator +=

//添加字符
string& operator+=(char ch)
{push_back(ch);return *this;
}
//添加字符串
string& operator+=(const char* str)
{append(str);return *this;
}

22.operator<<

//输出输入流只能用引用接受和返回
ostream& operator<<(ostream& out, const string& s)
{for (auto ch : s){out << ch;}return out;
}

23.operator>>

ostream& operator>>(ostream& in, string& s)
{s.clear();char ch = in.get();while (ch == ' ' || ch == '&'){ch = in.get();}char buff[128];int i = 0;while (ch != ' ' && ch != '\n'){if (i == 127){buff[i++] = '\0';i = 0;s += buff;}s += ch;ch =in.get();}if (i != 0){buff[i] = '\0';s += buff;}return in;
}

24.resize()

//设置有效字符大小,如果比原先小则保持不变,如果比原先大则在尾部添加。
void resize(size_t n, char c = '\0')
{if (n < _size){_size = n;_str[_size] = '\0';}else{reserve(n);for (size_t i = _size; i < n; i++){_str[i] = c;}_size = n;_str[_size] = '\0';}
}

25.reserve()

//设置容量大小,只增不减
void reserve(size_t n)
{if (n > _capacity){char*  tmp = new char[n + 1];memcpy(tmp, _str, _size + 1);_capacity = n;delete[] _str;_str = tmp;	}
}

26.substr()

string substr(size_t pos = 0, size_t len = npos)
{assert(pos < _size);int n = 0;if (len == npos || pos + len >= _size){n = _size - pos;}string tmp;tmp.reserve(n);for (size_t i = pos; i < pos+n; i++){tmp+=_str[i];//为什么不加\0 }return tmp;
}

在这里插入图片描述

相关文章:

c++系列之string的模拟实现

&#x1f497; &#x1f497; 博客:小怡同学 &#x1f497; &#x1f497; 个人简介:编程小萌新 &#x1f497; &#x1f497; 如果博客对大家有用的话&#xff0c;请点赞关注再收藏 &#x1f31e; string() //注意事项&#xff1a; 1.初始化列表随声明的顺序进行初始化 2.cons…...

Spring的beanName生成器AnnotationBeanNameGenerator

博主介绍&#xff1a;✌全网粉丝4W&#xff0c;全栈开发工程师&#xff0c;从事多年软件开发&#xff0c;在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战&#xff0c;博主也曾写过优秀论文&#xff0c;查重率极低&#xff0c;在这方面有丰富的经验…...

FFmpeg 命令:从入门到精通 | ffmpeg 命令直播

FFmpeg 命令&#xff1a;从入门到精通 | ffmpeg 命令直播 FFmpeg 命令&#xff1a;从入门到精通 | ffmpeg 命令直播直播拉流直播推流 FFmpeg 命令&#xff1a;从入门到精通 | ffmpeg 命令直播 本节主要介绍了ffmpeg 命令进行直播拉流、推流的方法&#xff0c;并列举了一些例子…...

A (1087) : DS单链表--类实现

Description 用C语言和类实现单链表&#xff0c;含头结点 属性包括&#xff1a;data数据域、next指针域 操作包括&#xff1a;插入、删除、查找 注意&#xff1a;单链表不是数组&#xff0c;所以位置从1开始对应首结点&#xff0c;头结点不放数据 类定义参考 #include<…...

异常:找不到匹配的key exchange算法

目录 问题描述原因分析解决方案 问题描述 PC 操作系统&#xff1a;Windows 10 企业版 LTSC PC 异常软件&#xff1a;XshellPortable 4(Build 0127) PC 正常软件&#xff1a;PuTTY Release 0.74、MobaXterm_Personal_23.1 服务器操作系统&#xff1a;OpenEuler 22.03 (LTS-SP2)…...

Arcgis打开影像分析窗口没反应

Arcgis打开影像分析窗口没反应 问题描述 做NDVI计算的时候&#xff0c;一直点击窗口-影像分析&#xff0c;发现影像分析的小界面一直不跳出来。 原因 后来发现是被内容列表给遮住了&#xff0c;其实是已经出来了的。。 拖动内容列表就能找到。 解决方案 内容列表和影像分…...

Spring(JavaEE进阶系列1)

目录 前言&#xff1a; 1.Servlet与Spring对比 2.什么是Spring 2.1什么是容器 2.2什么是IoC 2.3SpringIoC容器的理解 2.4DI依赖注入 2.5IoC与DI的区别 3.Spring项目的创建和使用 3.1正确配置Maven国内源 3.2Spring的项目创建 3.3将Bean对象存储到Spring&#xff08…...

Flink状态管理与检查点机制

1.状态分类 相对于其他流计算框架,Flink 一个比较重要的特性就是其支持有状态计算。即你可以将中间的计算结果进行保存,并提供给后续的计算使用: 具体而言,Flink 又将状态 (State) 分为 Keyed State 与 Operator State: 1.1 算子状态 算子状态 (Operator State):顾名思义…...

【threejs】基本编程概念及海岛模型展示逻辑

采用three封装模式完成的海岛动画&#xff08;点击这里查看&#xff09; 直接上代码吧 <template><div class"scene"><video id"videoContainer" style"position:absolute;top:0px;left:0px;z-index:100;visibility: hidden"&g…...

python小技巧:创建单链表及删除元素

目前只有单链表&#xff08;无法查找上一个元素&#xff09;&#xff0c;后面再更新循环链表和双链表。 class SingleLinkedList:def createList(self, raw_list):if len(raw_list) 0:head ListNode()else:head ListNode(raw_list[0])cur headfor i in range(1, len(raw_l…...

ADuM1250 ADuM1251 模块 I2C IIC总线2500V电磁隔离 接口保护

功能说明&#xff1a; 1&#xff0c;2500V电磁隔离&#xff0c;2通道双向I2C&#xff1b; 2&#xff0c;支持电压在3到5.5V&#xff0c;最大时钟频率可达1000KHz&#xff1b; 3&#xff0c;将该隔离模块接入总线&#xff0c;可以保护主MCU引脚&#xff0c;降低I2C总线上的干…...

C# 把多个dll合成一个dll

Nuget 下载ILMerge两个工程 dog为测试工程 TestIlmerge为准备合并的类库 如下图所示&#xff0c; 由于我们引用下面4个库 正常生成后&#xff0c;会有TestIlmerge.dll和下面的这4个dll 只生成TestIlmerge.dll 打开工程文件 在最下方加入以下两段 <Target Name"ILMerge…...

scipy.sparse.coo_matrix.sum()关于axis的用法

以下面的矩阵为例 [1,2,0] [0,3,0] [0,0,0]示例代码 from scipy.sparse import coo_matrix# 创建一个稀疏矩阵 data [1, 2, 3] row [0, 0, 1] col [0, 1, 1] sparse_matrix coo_matrix((data, (row, col)), shape(3,3))# 计算稀疏矩阵中每行非零元素的总和 sum_of_column…...

C++类与对象(下)

文章目录 1.非类型模板2.模板特化2.1.类模板特化2.1.1.全特化2.1.2.偏特化 2.2.函数模板特化 3.函数模板声明定义分离 之前我们学习的模板能达到泛型的原因是&#xff1a;使用了“泛型的类型”&#xff0c;但是如果经过后面的“造轮子”&#xff08;后面会尝试实现一下 STL的一…...

SpringBoot——》引入Redis

推荐链接&#xff1a; 总结——》【Java】 总结——》【Mysql】 总结——》【Redis】 总结——》【Kafka】 总结——》【Spring】 总结——》【SpringBoot】 总结——》【MyBatis、MyBatis-Plus】 总结——》【Linux】 总结——》【MongoD…...

C# newtonsoft序列化将long类型转化为字符串

/// <summary> /// 转化为json的时候long类型转为string /// </summary> public class LongJsonConverter: JsonConverter {public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer){try{return r…...

黑马点评-02使用Redis代替session,Redis + token机制实现

Redis代替session session共享问题 每个Tomcat中都有一份属于自己的session,所以多台Tomcat并不共享session存储空间,当请求切换到不同tomcat服务时可能会导致数据丢失 用户第一次访问1号tomcat并把自己的信息存放session域中, 如果第二次访问到了2号tomcat就无法获取到在1号…...

arm 点灯实验代码以及现象

.text .global _start _start: 1.设置GPIOE寄存器的时钟使能 RCC_MP_AHB4ENSETR[4]->1 0x50000a28 LDR R0,0x50000A28 LDR R1,[R0] ORR R1,R1,#(0x1<<4) 第4位置1 STR R1,[R0] 1.设置GPIOF寄存器的时钟使能 RCC_MP_AHB4ENSETR[4]->1 0x50000a28 LDR R…...

选择适合普通公司的项目管理软件

不管是打工人还是学生党都适合使用Zoho Projects项目管理软件。利用项目概览功能&#xff0c;将整体项目尽收眼底&#xff0c;作为项目管理者&#xff0c;项目日程、进度都可见&#xff0c;Zoho Projects项目管理APP助推项目每一环节的进展&#xff0c;更便于管理者设计项目的下…...

E (1081) : DS堆栈--逆序输出(STL栈使用)

Description C中已经自带堆栈对象stack&#xff0c;无需编写堆栈操作的具体实现代码。 本题目主要帮助大家熟悉stack对象的使用&#xff0c;然后实现字符串的逆序输出 输入一个字符串&#xff0c;按字符按输入顺序压入堆栈&#xff0c;然后根据堆栈后进先出的特点&#xff0…...

stm32G473的flash模式是单bank还是双bank?

今天突然有人stm32G473的flash模式是单bank还是双bank&#xff1f;由于时间太久&#xff0c;我真忘记了。搜搜发现&#xff0c;还真有人和我一样。见下面的链接&#xff1a;https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...

docker详细操作--未完待续

docker介绍 docker官网: Docker&#xff1a;加速容器应用程序开发 harbor官网&#xff1a;Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台&#xff0c;用于将应用程序及其依赖项&#xff08;如库、运行时环…...

大话软工笔记—需求分析概述

需求分析&#xff0c;就是要对需求调研收集到的资料信息逐个地进行拆分、研究&#xff0c;从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要&#xff0c;后续设计的依据主要来自于需求分析的成果&#xff0c;包括: 项目的目的…...

Zustand 状态管理库:极简而强大的解决方案

Zustand 是一个轻量级、快速和可扩展的状态管理库&#xff0c;特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...

大数据零基础学习day1之环境准备和大数据初步理解

学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 &#xff08;1&#xff09;设置网关 打开VMware虚拟机&#xff0c;点击编辑…...

蓝桥杯 2024 15届国赛 A组 儿童节快乐

P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡&#xff0c;轻快的音乐在耳边持续回荡&#xff0c;小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下&#xff0c;六一来了。 今天是六一儿童节&#xff0c;小蓝老师为了让大家在节…...

【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表

1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

保姆级教程:在无网络无显卡的Windows电脑的vscode本地部署deepseek

文章目录 1 前言2 部署流程2.1 准备工作2.2 Ollama2.2.1 使用有网络的电脑下载Ollama2.2.2 安装Ollama&#xff08;有网络的电脑&#xff09;2.2.3 安装Ollama&#xff08;无网络的电脑&#xff09;2.2.4 安装验证2.2.5 修改大模型安装位置2.2.6 下载Deepseek模型 2.3 将deepse…...

使用LangGraph和LangSmith构建多智能体人工智能系统

现在&#xff0c;通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战&#xff0c;比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...