【C++】手动模拟String底层与深浅拷贝

在string类:版本、组件、构造、操作及应用和 C++中string的一些超常用函数 (附习题)这两篇文章中我们已经了解到了string,现在让我们再来手动实现模拟一下吧~

模拟实现string是为了更好的理解string函数的使用深浅拷贝方面的知识~

总体整理了两张思维导图,大概是这个样子的,XMind资源已经上传啦,可以按需下载~

整体代码

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
namespace yzq
{class string{public://string()//无参构造函数//	//初始化列表//	:_str(new char[1])//为了析构都是用delete[],匹配使用//	,_size(0)//	,_capaicty(0)//{//	_str[0] = '\0';//}//string(const char*str)//带参构造函数//	//	 :_size(strlen(str))//{//     _capaicty = _size;//	 _str = new char[_capaicty+1];//因为有'\0'的存在所以多开一个空间//	 strcpy(_str, str);//拷贝//}typedef char* iterator;typedef const char* const_iterator;iterator begin(){return _str;}iterator end(){return _str + _size;}iterator begin()const {return _str;}iterator end()const{return _str + _size;}string(const char* str="")//构造函数:_size(strlen(str)){if (_size == 0){_capacity = 3;}else{_capacity = _size;}_str = new char[_capacity + 1];strcpy(_str, str);}string(const string& s)//拷贝构造:_size(s._size),_capacity(s._capacity){//深拷贝_str = new char[_capacity + 1];//开辟一块空间strcpy(_str, s._str);//将s2的值传给s1}string& operator=(const string& s)//赋值 s1=s3{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;}size_t size()const{return _size;}const char* C_str()//返回const char*类型的指针 {return  _str;}char& operator[](size_t pos)//operator[]{return _str[pos];}char& operator[](size_t pos)const //函数重载{return _str[pos];}bool operator==(const string& s)const //s1==s2{return strcmp(_str, s._str)==0;}bool operator<(const string& s)const //s1<s2{return strcmp(_str, s._str) < 0;}bool operator<=(const string& s)const //s1<=s2{return *this < s || *this == s;}bool operator>(const string& s)const //s1>s2{return !(*this <= s);}bool operator>=(const string& s)const //s1>=s2{//复用return *this > s || *this == s;}bool operator!=(const string& s)const //s1!=s2{return !(*this == s);}void reserve(size_t n)//开辟空间{if (n > _capacity)//防止缩容的问题{char* tmp = new char[n + 1];//多开一个'\0'strcpy(tmp, _str);delete[]_str;_str = tmp;_capacity = n;//计算有效}}void resize(size_t n,char ch)//开辟空间+初始化{if (n <= _size)//删除数据保留前n个{_size = n;_str[n] = '\0';}else //n>_size{if (n >_capacity)//扩容{reserve(n);}int i = _size;while (i < n){_str[i] = ch;i++;}_size = n;_str[_size] = '\0';}}void push_back(char ch)//尾插字符{if (_size + 1 > _capacity){reserve(2 * _capacity);//开辟2倍空间}_str[_size] = ch;_size++;//ch是一个字符,所以用单独处理'\0'_str[_size] = '\0';}void append(const char* str)//尾插 字符串{ int len = strlen(str);if (_size + len > _capacity){reserve(_size + len);}strcpy(_str + _size, str);//在原来的字符串后拷贝字符串_size += len;//str是一个字符串,本身带'\0'}string& operator+=(char ch)//+= 字符{push_back(ch);return *this;}string& operator+=(const char* str)//+= 字符串 函数重载{append(str);return *this;}string& insert(size_t pos, char ch)//在pos位置前插入字符ch{if (_size + 1 > _capacity)//扩容{reserve(2 * _capacity);}size_t end = _size + 1;while (end > pos){//把前面传给后面_str[end] = _str[end - 1];end--;}_str[pos] = ch;_size++;return *this;}string& insert(size_t pos, const char* str)//在pos位置前插入字符串str{int len = strlen(str);if (_size + len > _capacity)//扩容{reserve(_size + len);}size_t end = _size + len;while (end > pos+len-1){//把前面传给后面_str[end] = _str[end-len];end--;}strncpy(_str + pos, str, len);//拷贝len个字节,不包含'\0'_size += len;return *this;}static const size_t npos = -1;string& erase(size_t pos = 0, size_t len = npos)//从pos位置开始删除len个数据{if (len==npos||pos+len>=_size){//全部删除_str[pos] = '\0';_size = pos;}else{strcpy(_str + pos, _str +pos+len);//包含'\0'_size -= len;}return *this;}void swap(string &s)//交换{std::swap(_str, s._str);std::swap(_capacity, s._capacity);std::swap(_size, s._size);}size_t find(char c, size_t pos =0){int i = 0;for (i = pos; i < size(); i++){if (_str[i] == c){return i;}}return npos;	}size_t find(const char* str, size_t pos = 0)//从pos位置开始找子串{char*p=strstr(_str+pos, str);if (p == nullptr){return npos;}else{return p - _str;//指针相减为个数}}void clear()//清空{_str[0] = '\0';}~string()//析构{delete[]_str;_str = nullptr;_size = 0;_capacity = 0;}private:char* _str;size_t _size;size_t _capacity;};ostream& operator<<(ostream& out, const string&s)//<<{int i = 0;for (i = 0; i < s.size(); i++){out << s[i];}return out;}istream& operator>>(istream& in,  string& s)//>>{s.clear();char ch = in.get();char buf[128];size_t index = 0;while (ch != ' ' && ch != '\n'){buf[index++] = ch;if (index == 127)//为了防止频繁扩容{buf[127] = '\0';s += buf;index = 0;}ch = in.get();}if (index != 0){buf[index] = '\0';s += buf;}return in;}void print(const string& s){string::const_iterator it = s.begin();while (it != s.end()){cout << *it << " ";it++;}cout << endl;}void test(){string s1;cin >> s1;cout << s1;}
}

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

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

相关文章

【Python编程】【Jupyter Notebook】启动时报错:no available port could be found

一、报错描述 在Jupyter Notebook中编写程序&#xff0c;无法运行&#xff0c;提示由于没有可供监听的端口&#xff0c;无法启动Jupyter服务器&#xff0c;如下图所示&#xff1a; 二、原因分析 通过报错信息&#xff0c;猜测大概是由于网络环境的原因。首先&#xff0c;关闭…

C语言(结构体)

Hi~&#xff01;这里是奋斗的小羊&#xff0c;很荣幸各位能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎~~ &#x1f4a5;个人主页&#xff1a;小羊在奋斗 &#x1f4a5;所属专栏&#xff1a;C语言 本系列文章为个人学习笔记&#xff0c;在这里撰写成文一…

AIGC实战!7个超热门的 Midjourney 关键词教程

一、剪纸风格 核心词&#xff1a; paper art&#xff08;剪纸艺术&#xff09; 关键技巧&#xff1a; 主体物&#xff1a;可以换成任意主角&#xff0c;Chinese illustration &#xff08;中国风插画&#xff09;&#xff1b;艺术风格&#xff1a;paper art &#xff08;剪纸…

ruoyi vue 集成积木报表真实记录

按官方文档集成即可 积木报表官方集成文档 集成问题 1.注意 idea 配置的 maven 需要设置成 本地配置&#xff0c;不可以使用 idea 自带的 maven,自带 maven 会导致私有源调用不到 后端代码 新建 base 模块 maven配置 <project xmlns"http://maven.apache.org/POM/…

微软云计算[3]之Windows Azure AppFabric

Windows Azure AppFabric AppFabric概述AppFabric关键技术服务总线访问控制高速缓存 AppFabric概述 AppFabric为本地应用和云中应用提供了分布式的基础架构服务 用户本地应用与云应用之间进行安全联接和信息传递 云应用和现有应用或服务之间的连接及跨语言、跨平台、跨不同标…

C++数据结构之:哈希表Hash

摘要&#xff1a; it人员无论是使用哪种高级语言开发东东&#xff0c;想要更高效有层次的开发程序的话都躲不开三件套&#xff1a;数据结构&#xff0c;算法和设计模式。数据结构是相互之间存在一种或多种特定关系的数据元素的集合&#xff0c;即带“结构”的数据元素的集合&am…

鸿蒙开发 之 ArkUI路由

1.页面路由 页面路由是指在应用程序中实现不同页面之间的跳转和数据传递 比如说你打开一个app&#xff0c;首先进入的是登陆页&#xff0c;首页&#xff0c;列表搜索页&#xff0c;详情页&#xff0c;你打开几个页面都会存储在页面栈里&#xff0c;页面栈的最大容量上限为32个&…

在Oracle VM virtual box 中复制 CentOS 7虚拟机更改IP地址的操作

最近玩Redis主从复制的时候&#xff0c;我装了一个虚拟机&#xff0c;但主从复制需要准备3个虚拟机&#xff0c;这个时候&#xff0c;我又不想一个一个去装&#xff0c;我看到Oracle VM virtual box提供了一个虚拟机复制操作&#xff0c;于是就用了一下这个功能&#xff0c;发现…

云原生时代:从 Jenkins 到 Argo Workflows,构建高效 CI Pipeline

作者&#xff1a;蔡靖 Argo Workflows Argo Workflows [ 1] 是用于在 Kubernetes 上编排 Job 的开源的云原生工作流引擎。可以轻松自动化和管理 Kubernetes 上的复杂工作流程。适用于各种场景&#xff0c;包括定时任务、机器学习、ETL 和数据分析、模型训练、数据流 pipline、…

【成品设计】基于STC15F104W的互补PWM输出器

《基于STC15F104W的互补PWM输出器》 1.所需器件&#xff1a; (1)单片机&#xff1a;STC15F104W。 ①最小系统板链接&#xff1a;【淘宝】https://m.tb.cn/h.5WnLl9X?tkqSGrdCWm0PW「STC15F104W STC15W204S单片机模块 系统板 核心板 学习板 开发板」点击链接直接打开 或者 淘宝…

HCIP-Datacom-ARST自选题库__多种协议简答【11道题】

1.BGP/MPLSIP VPN的典型组网场景如图所示&#xff0c;PE1和PE2通过LoopbackO建立MP-IBGP&#xff0c;PE1和PE2之间只传递VPN路由&#xff0c;其中PE1BGP进程的部分配置已在图中标出&#xff0c;则编号为0的命令不是必须的。(填写阿拉伯数字) 3 2.在如图所示的Hub&amp;Spok…

【Java】数据加密

目录 数据加密介绍使用场景密码学历史古代密码学凯撒密码例子特点 维吉尼亚密码原理例子特点 现代密码学介绍 现代密码学的加密算法分类哈希算法优点缺点代码示例【封装写法】 对称加密算法对称加密算法的加密过程解密过程对称加密算法的优点&#xff1a;对称加密算法的缺点&am…

【初识Objective-C】

Objective-C学习 什么是OCOC的特性OC跑的第一个程序helloworld OC的一些基础知识标识符OC关键字数据类型字符型c字符串为什么NSString类型定义时前面要加和普通的c对象有什么区别 一些基础知识if语句switch语句三种循坏语句for循环&#xff1a;用于固定次数的循环while循环&…

低功耗,低噪声 CMOS 轨到轨输入输出运算放大器

产品简述 MS6001/2/4 运算放大器具有极低功耗&#xff0c;轨到轨输入输出&#xff0c;低 的输入电压和低的电流噪声。具体表现在可工作在幅度为 1.8V 到 5V 的单电源或者双电源条件&#xff0c;低功耗和低噪声使得 MS6001/2/4 能够用在可移动设备上&#xff0c;输入输…

低代码/无代码可以降低程序员哪些门槛

低代码/无代码开发平台是一种新兴的软件开发模式&#xff0c;它通过图形化界面、拖拽式操作等方式&#xff0c;快速构建应用程序&#xff0c;从而降低了开发者的准入门槛。这种模式对程序员来说&#xff0c;不仅可以提高开发效率&#xff0c;还可以在某些情况下促进业务人员成为…

目标检测数据集 - 打架检测数据集下载「包含VOC、COCO、YOLO三种格式」

数据集介绍&#xff1a;打架检测数据集&#xff0c;真实监控场景高质量打架图片数据&#xff0c;涉及场景丰富&#xff0c;比如街道场景打架数据、酒吧场景打架数据、商店场景打架数据、公交车场景打架数据、监狱场景打架数据、空旷地打架数据、两人打架数据、多人群殴数据等。…

面试官:如何实现大文件切片上传?

公众号&#xff1a;程序员白特&#xff0c;关注我&#xff0c;每天进步一点点~ 前端上传文件很大时,会出现各种问题,比如连接超时了,网断了,都会导致上传失败,这个时候就需要将文件切片上传,下面我们就来学习一下如何使用vue实现大文件切片上传吧 大文件为什么要切片上传 前端…

【SpringBoot】SpringBoot同时可以处理多少请求

目录 问题Web三大容器三者区别TomcatJetty小结 最大连接数和最大等待数同时处理请求数拓展&#xff1a;设置Web容器设置容器为Jetty设置容器为Undertow 问题 之前看到过一个面试题&#xff1a;SpringBoot同时可以处理多少请求&#xff1f; 准确的来说&#xff0c;Spring Boot…

pycharm绘图时中英文不能同时出现 中文出现小框框的问题解决

# 设置字体为微软雅黑&#xff0c;正确显示负号 plt.rcParams[font.sans-serif] [Microsoft YaHei] plt.rcParams[axes.unicode_minus] False

Python 组合序号

import pandas as pd # 创建一个示例数据框 data { group: [A, A, A, B, B, C, C, C, C], value: [3, 1, 2, 5, 4, 6, 9, 7, 8] } df pd.DataFrame(data) # 先按group分组&#xff0c;再按value列升序排序 df_sorted_asc df.sort_values(by[group, value]) # 使…