C++:string的模拟实现

目录

1.string的四大默认函数

1.1构造函数

1.2析构函数

1.3拷贝构造

1.4赋值运算符重载

2.访问string的三种方式

2.1[]访问

2.2迭代器访问

2.3范围for(本质是迭代器)

3.string相关功能的实现

3.1modify

3.2capacity

3.3access

3.4relations

3.5补充

4.补充


1.string的四个默认函数

1.1构造函数

		//构造函数String(const char* str = ""):_size(strlen(str)){if (str == nullptr) exit(-1);_capacity = _size == 0 ? 3 : _size;_str = new char[_capacity + 1];strcpy(_str,str);}

1.2析构函数

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

1.3拷贝构造

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

1.4赋值运算符重载

		//赋值运算符String& operator=(const String& s) {if (this != &s) {char* tmp = new char[strlen(s._str)+1];strcpy(tmp,s._str);delete[] _str;_str = tmp;_size = s._size;_capacity = s._capacity;}return *this;}

2.访问string的三种方式

2.1[]访问

		char& operator[](size_t pos) {return *(_str + pos);}

2.2迭代器访问

		//迭代器typedef char* iterator;typedef const char* const_iterator;iterator begin() {return _str;}iterator begin()const{return _str;}iterator end(){return _str + _size;}iterator end()const{return _str + _size;}

2.3范围for(本质是迭代器)

	//范围forcout << "范围for: ";for (auto ch : s1) {cout << ch;}

3.string相关功能的实现

3.1modify

-push_back

		//尾插一个字符void push_back(char ch) {//检查是否扩容if (_size + 1 > _capacity)reserve(2*_capacity);//插入数据_str[_size] = ch;++_size;_str[_size] = '\0';}

-+= 字符

		//重载String& operator+=(char ch) {push_back(ch);return *this;}

-append

		//appendvoid append(const char* str) {int len = strlen(str);if (_size + len > _capacity) //扩容{reserve(_capacity + len);}//插入数据strcat(_str,str);_size += len;}

-+=字符串

		//重载+=String& operator+=(const char* str) {append(str);return *this;}

-clear

		//clearvoid clear() {_size = 0;_str[_size] = '0';}

-swap

		//swapvoid swap(String& s) {std::swap(_str,s._str);std::swap(_size,s._size);std::swap(_capacity, s._capacity);}

-C格式字符串

		//C格式的字符串const char* c_str()const{return _str;}

3.2capacity

-size

		//获取长度size_t size()const{return _size;}

-capacity

		//获取容量size_t size()const{return _capacity;}

-bool empty

		bool empty()const{return _size == 0;}

-reserve(扩容)

		//reserve(扩容)void reserve(size_t n){if (n < _size) //删除数据{_str[n] = '\0';}if (n > _capacity){//拷贝原来的数据char* tmp = new char[n + 1];strcpy(tmp, _str);delete[] _str;_str = tmp;_capacity = n;}}

-resize

		void resize(size_t n,char ch = '\0'){if (n < _size) {_size = n;//删除数据_str[_size] = '\0';}else //n>=_size{if (n > _capacity){reserve(n);}//将剩余的字符初始化size_t i = _size;while (i < n){_str[i] = ch;i++;}_size = n;//改变size大小_str[_size] = '\0';}}

3.3access

		// accesschar& operator[](size_t pos){return *(_str + pos);}char& operator[](size_t pos)const{return *(_str + pos);}

3.4relations

		//relational operatorsbool operator<(const String& s) {return strcmp(_str, s._str) < 0;}bool operator <=(const String& s){return strcmp(_str, s._str) <= 0;}bool operator>(const String& s){return strcmp(_str, s._str) > 0;}bool operator >=(const String& s){return strcmp(_str, s._str) >= 0;}bool operator==(const String& s) {return strcmp(_str,s._str) == 0;}bool operator!=(const String& s){return strcmp(_str, s._str) != 0;}

3.5补充

1.-find     //返回c再string中第一次出现的位置

		//返回c再string中第一次出现的位置size_t find(char c,size_t pos = 0) {assert(pos < _size);while (pos< _size) {if (_str[pos] == c) {return pos;}pos++;}return npos;}

--find   //字符串

		//返回子字串在string中第一次出现的位置size_t find(const char* str, size_t pos = 0)const{return strstr(_str,str+pos) - _str - pos;}

2.//在pos位置上插入字符c/字符串str,并返回该字符的位置

-字符

		//在pos位置上插入字符c/字符串str,并返回该字符的位置size_t insert(size_t pos ,char ch ){assert(pos < _size);//判断是否需要扩容if (_size + 1 > _capacity) {reserve(2*_capacity);}//从后往前挪动数据size_t end = _size + 1;while (end > pos) {_str[end] = _str[end - 1];end--;}//在pos位置插入数据_str[pos] = ch;//更新_size_size++;return pos;}

-字符串

size_t insert(size_t pos, const char* str) {assert(pos < _size);size_t len = strlen(str);//扩容if (_size + len > _capacity) {reserve(_capacity + len);}//挪动数据size_t end = _size + len;while (end - len > pos) {_str[end] = _str[end - len];end--;}//在pos位置插入字符串strncpy(_str + pos ,str,len);//更新_size_size += len;return pos;}

//删除数据

		// 删除pos位置上的元素,并返回该元素的下一个位置String& erase(size_t pos,size_t len) {assert(pos < _size);//将pos后的数据删完if (len == npos || pos + len > _size) {_str[pos] = '\0';_size = pos ;}else //删除一部分{//把删除len后面的数据拷贝到pos后strcpy(_str + pos ,_str + pos + len);_size -= len;}return *this;}

3.>>与<<的重载

<<

	ostream& operator<<(ostream& _cout, const my_func::String& s){for (auto e : s){_cout << e;}_cout << endl;return _cout;}

>>

	istream& operator>>(istream& _cin,my_func::String& s){	s.clear();//清空之前的内容//先往数组里面放,满了/读取到'\n'再往s里面放//这样避免频繁的扩容char buff[128];char ch = cin.get();size_t i = 0;while (ch != '\n'){buff[i++] = ch;if (i == 127) {s += buff;//满了往s里面加i = 0;}ch = cin.get();//继续读取}if (i != 0) {s += buff;}return _cin;}

4.补充

1.reserve与resize

reserve不会改变_size的大小(有效元素的个数)

(当reserve的参数小于string的底层空间总大小时,reserver不会改变容量大小。)

resize会改变并且用字符初始化多出来的空间

(resize在改变元素个数时,如果是将元素个数增多,可能会改变底层容量的大小,如果是将元素个数减少,底层空间总大小不变)

2.str与c_str

  • c_str是string类提供的成员函数,用于将string对象转换为C风格的字符串(以空字符结尾的字符数组)。

示例:

c_str在使用cout打印的时候,遇到\0就会停止打印

str    在使用重载后的<<打印,是按_size打印的

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

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

相关文章

C++之哈希表、哈希桶的实现

哈希表、哈希桶的实现 哈希概念哈希冲突哈希函数哈希冲突解决闭散列哈希表闭散列实现哈希表的结构哈希表的插入哈希表的查找哈希表的删除 开散列开散列概念哈希表的结构哈希表的插入哈希表的查找哈希表的删除 哈希概念 顺序结构以及平衡树中&#xff0c;元素关键码与其存储位置…

git everything up-to-date解决方法

git push origin master 总是提示git everything up-to-date,原因是远端没有分支 . 操作如下:(1)查看当前分支名 git branch -av(2)git push --set-upstream origin (当前分支名)

Linux-相关操作

2.2.2 Linux目录结构 /&#xff1a;根目录&#xff0c;一般根目录下只存放目录&#xff0c;在Linux下有且只有一个根目录。所有的东西都是从这里开始。当你在终端里输入“/home”&#xff0c;你其实是在告诉电脑&#xff0c;先从/&#xff08;根目录&#xff09;开始&#xf…

P2239 [NOIP2014 普及组] 螺旋矩阵

题目链接&#xff1a; 找到矩阵元素与 n , i , j \rm n, i, j n,i,j之间的关系&#xff0c;然后直接输出 #include <bits/stdc.h>using namespace std;int find(int n, int i, int j) {if (i 1) return j;if (j n) return i n - 1;if (i n) return 3 *n - 1 - j;if …

广州xx策划公司MongoDB恢复-2023.09.09

2023.09.08用户的MongoDB数据库被勒索病毒攻击&#xff0c;数据全部被清空。 提示&#xff1a; mongoDB的默认端口为27017&#xff0c;黑客通常通过全网段扫描27017是否开放判断是否是MongoDB服务器。一旦发现27017开放&#xff0c;黑客就会用空密码、弱密码尝试连接数据库。黑…

Mojo-SDK详细安装教程

Mojo-SDK安装 运行环境&#xff1a;windows11wsl2&#xff08;ubuntu1804&#xff09; 官方推荐&#xff1a;wsl2&#xff08;ubuntu2204&#xff09;&#xff0c;我下面是wsl2&#xff08;ubuntu1804&#xff09;&#xff0c;发现有些问题&#xff0c;不知道是不是ubuntu版本问…

opencv dnn模块 示例(16) 目标检测 object_detection 之 yolov4

博客【opencv dnn模块 示例(3) 目标检测 object_detection (2) YOLO object detection】 测试了yolov3 及之前系列的模型&#xff0c;有在博客【opencv dnn模块 示例(15) opencv4.2版本dnn支持cuda加速&#xff08;vs2015异常解决&#xff09;】 说明了如何使用dnn模块进行cuda…

kafka 3.5 主题分区ISR伸缩源码

ISR(In-sync Replicas)&#xff1a;保持同步的副本 OSR(Outof-sync Replicas)&#xff1a;不同步的副本。最开始所有的副本都在ISR中&#xff0c;在kafka工作的过程中&#xff0c;如果某个副本同步速度慢于replica.lag.time.max.ms指定的阈值&#xff0c;则被踢出ISR存入OSR&am…

(1)输入输出函数:cin和cout(2)数学函数:sqrt、pow、sin、cos、tan等

输入输出函数&#xff1a;cin 和 cout 在C编程语言中&#xff0c;为了与用户进行交互和显示程序的结果&#xff0c;我们使用了两个非常重要的函数&#xff1a;cin 和 cout。这两个函数分别用于输入和输出。 cin是C中的标准输入流对象&#xff0c;它用于从键盘接收用户的输入。…

SQL12 高级操作符练习(2)

描述 题目&#xff1a;现在运营想要找到学校为北大或GPA在3.7以上(不包括3.7)的用户进行调研&#xff0c;请你取出相关数据&#xff08;使用OR实现&#xff09; 示例&#xff1a;user_profile iddevice_idgenderageuniversitygpa12138male21北京大学3.423214male复旦大学4.03…

六、不root不magisk不xposed lsposed frida原生修改定位

前言常用风控APP检测1.Aida64检测2.momo检测3.微霸检测4.cellular-z检测 厂商测试总结 前言 不root不戴面具 不xposed lsposed frida&#xff0c;不分身&#xff0c;不多开&#xff0c;最完美的原生修改定位。 常用风控APP检测 先看效果再说原理&#xff0c;先过一遍环境 1.Ai…

聚类分析 | MATLAB实现基于SOM自组织特征映射聚类可视化

聚类分析 | MATLAB实现基于SOM自组织特征映射聚类可视化 目录 聚类分析 | MATLAB实现基于SOM自组织特征映射聚类可视化效果一览基本介绍程序设计参考资料 效果一览 基本介绍 基于自组织特征映射聚类算法(SOM)的数据聚类可视化 可直接运行 注释清晰 Matlab语言 1.多特征输入&…

Python 可迭代对象、迭代器、生成器

可迭代对象 定义 在Python的任意对象中&#xff0c;只要它定义了可以返回一个迭代器的 __iter__ 魔法方法&#xff0c;或者定义了可以支持下标索引的 __getitem__ 方法&#xff0c;那么它就是一个可迭代对象&#xff0c;通俗的说就是可以通过 for 循环遍历了。Python 原生的列…

爬虫 — 正则案例

目录 一、需求二、页面分析三、代码实现 一、需求 目标网站&#xff1a;http://www.weather.com.cn/weather/101010700.shtml 需求&#xff1a;获取日期&#xff0c;天气&#xff0c;温度&#xff0c;风力数据 二、页面分析 1、确定 url&#xff0c;静态加载 url&#xff1a;ht…

Mybatis的mapper.xml批量插入、修改sql

今天要有个功能&#xff0c;要进行一批数据的插入和修改&#xff0c;为了不频繁调用数据库&#xff0c;所以想到了批量插入和修改&#xff0c;因为从毕业后&#xff0c;就没写过批量插入和批量修改&#xff0c;所以在这里记录一下&#xff0c;避免后续再遇到忘记怎么写了 批量…

【小记录】jupyter notebook新版本

手欠升级 &#x1f605;今天手贱&#xff0c;在anaconda navigator里面更新了最新版本的spyder&#xff0c;然后莫名奇妙地jupyter notebook就打不开了&#x1f605;&#xff0c;报错说缺少模块”ModuleNotFoundError: No module named jupyter_server.contents“&#xff0c;…

Python分享之对象的属性

Python一切皆对象(object)&#xff0c;每个对象都可能有多个属性(attribute)。Python的属性有一套统一的管理方案。 属性的__dict__系统 对象的属性可能来自于其类定义&#xff0c;叫做类属性(class attribute)。类属性可能来自类定义自身&#xff0c;也可能根据类定义继承来的…

docker挂载目录权限问题

虽然是root身份进入docker但是依然有些权限是没有的&#xff01; 一、docker权限参数 可以解决挂载目录操作权限低 使用–privilegedtrue和-u参数来给Docker容器授权 docker run -it --privilegedtrue -uroot --namemysqlTest -v /root/data:/root/data_container mysql:5.7…

从0到1学会Git(第三部分):Git的远程仓库链接与操作

写在前面:前面两篇文章我们已经学会了git如何在本地进行使用&#xff0c;这篇文章将讲解如何将本地的git仓库和云端的远程仓库链接起来并使用 为什么要使用远程仓库:因为我们需要拷贝我们的代码给别人以及进行协同开发&#xff0c;就需要有一个云端仓库进行代码的存储和同步&a…

常见的HTTP请求方式

目录 GET 请求 POST 请求 PUT 请求 DELETE 请求 PATCH 请求 HEAD 请求 OPTIONS 请求 HTTP&#xff08;Hypertext Transfer Protocol&#xff09;是一种用于传输数据的协议&#xff0c;它在互联网中扮演了至关重要的角色。HTTP请求方式定义了客户端与服务器之间的通信方式…