C++(string 类模拟实现)

前提知识:上一章介绍了库里面关于string的诸多接口,这章我要根据库里的相关接口,自己实现。


1.成员变量:

我们需要定义起始位置,已经有效字符个数和容量。

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

2.默认成员函数:

2.1构造函数

默认给的缺省值是空串

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

2.2拷贝构造函数 

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

2.3赋值构造

		//赋值构造  先调用拷贝构造string& operator = (string tmp){//	if (this != &s)//	{//		string tmp(s);//		//this->swap(tmp);//		swap(tmp);//	}//	return *this;swap(tmp);return *this;}

2.4析构函数

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

3其他成员函数

3.1交换

		//交换void swap(string s){std::swap(_str,s._str);std::swap(_size, s._size);std::swap(_capacity, s._capacity);}

3.2c_str函数

		//返回字符串首地址const char* c_str(){return _str;}

3.3元素个数

		// 返回元素个数size_t size(){return _size;}

3.4operator[ ]

3.4.1普通版本

		//根据下标寻找元素char& operator[](int pos){assert(pos < _size);return _str[pos];}

3.4.2const 版本

		//根据下标寻找元素 const版本const char& operator[](int pos) const{assert(pos < _size);return _str[pos];}

 

3.5迭代器和范围for

3.5.1普通迭代器版本

		typedef char* iterator;iterator begin(){return _str;}iterator end(){return _str + _size;}

3.5.2const迭代器版本

		const_iterator begin() const{return _str;}const_iterator end() const{return _str + _size;}

3.6扩容

3.6.1reserve

		//扩容 不需要返回值,改变容量和长度就行void reserve(size_t n){if (n > _capacity){char * tmp = new char[n + 1];//有结束标识符 \0memcpy(tmp, _str,_size + 1);delete [] _str;_str = tmp;_capacity = n;}}

3.6.2resize

		void resize(size_t n ,char ch = '\0'){if (n < _capacity){_size = n;_str[_size] = '\0';}else{reserve(n);for (int i = _size; i < n; ++i){_str[i] = ch;}_size = n;_str[_size] = '\0';}}

3.7尾插

3.7.1尾插字符push_back

		void push_back(char ch){//判断是否需要扩容if (_size == _capacity){reserve(_capacity == 0 ? 4 : _capacity * 2);}_str[_size] = ch;_size++;_str[_size] = '\0';//结束标志位}

3.7.2尾插字符串 append

		// 尾插 字符串void append(const char* string){size_t len = strlen(string);if (_size + len > _capacity){reserve(_size + len);}strcpy(_str + _size, string);_size += len;//无须给停止标志位,因为是字符串}

3.7.3连接重载 operator +=

		// += 实现尾插// this指针指向对象 ,对this解引用就是 对象内容string& operator +=(char ch){push_back(ch);return *this;}string& operator +=(const char *string){append(string);return *this;}

3.8插入insert

3.8.1插入字符

		//插入字符void insert(size_t pos,char ch, size_t n){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] = ch;}_size += n;}

3.8.2插入字符串

		//插入字符串void insert(size_t pos, char* str){assert(pos <= _size);size_t 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 (size_t i = 0; i < len; i++){_str[pos + i] = str[i];}_size += len;}

 

3.9擦除erase

		//擦除void erase(size_t pos, size_t n = npos){assert(pos <= _size);if (n == npos || pos + n >= _capacity){_str[pos] = '\0';_size = pos;_str[_size] = '\0';}else{size_t end = pos + n;while (end <= _size){_str[pos++] = _str[end++];}_size -= n;}}

3.10查找find

3.10.1查找字符

		//发现size_t find(char ch,size_t pos = 0){assert(pos < _size);for (size_t i = pos; i < _size; i++){if (_str[i] == ch){return i;}}return npos;}

3.10.2查找字符串

		//发现字符串size_t find(const char* str, size_t pos = 0){assert(pos < _size);const char* ptr = strstr(_str + pos, str);if (ptr){return ptr - _str;}else{return npos;}}

3.11返回子串substr

		// 从某个位置开始 返回长度的字符串string substr(size_t pos = 0, size_t len = npos){assert(pos < _size);size_t n = len;if (len == npos || pos + len > _capacity){n = _size - pos;}string tmp;//临时创建一个对象tmp.reserve(n);for (size_t i = 0; i < n; i++){tmp += _str[i];}return tmp;}

3.12清空clear

		//清空函数void clear(){_str[_size] = '\0';_size = 0;}

3.13比较

3.13.1 operator <()

	    //重载实现 string对象的<bool operator <(const string& s) const{int ret = memcmp(_str, s._str, _size < s._size?_size : s._size);  // 定义一个变量  用来接收 比较两个字符串 长度较小的那个,如果相等则为0,如果大于则为正值,如果小于则为负。return ret == 0 ? _size < s._size : ret < 0;}

3.13.2operator==()

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

3.13.3 operator<=()

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

3.13.4operator>()

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

3.13.5operator>=()

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

3.13.6operator!=()

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

3.14流插入、提取

3.14.1operator <<

	//流插入ostream& operator << (ostream& out, const string& s){for (auto ch : s){out << ch;}return out;}

3.14.2operator >>

	//流提取istream& operator >> (istream& in, string& s){s.clear();char ch = in.get();//定义一个字符接收//处理前面缓冲区的空格和换行while (ch == ' ' || ch == '\n'){ch = in.get();}char buff[128];int i = 0;while ( ch != '\n'){buff[i++] = ch;if (i == 127){buff[i] = '\0';s += buff;i = 0;}ch = in.get();}if (i != 0){buff[i] = '\0';s += buff;}return in;}

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

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

相关文章

力扣算法题:34、在排序数组中查找元素的第一个和最后一个位置.java版

版本说明 当前版本号[20230930]。 版本修改说明20230930初版 34.在排序数组中查找元素的第一个和最后一个位置 34. 在排序数组中查找元素的第一个和最后一个位置 给你一个按照非递减顺序排列的整数数组 nums&#xff0c;和一个目标值 target。请你找出给定目标值在数组中的…

MyBatisPlus(六)字段映射 @TableField

字段注解&#xff08;非主键&#xff09; TableField 用于映射对象的 属性 和表中的 字段 。 当 属性名 和 字段名 差异较大的时候&#xff0c;无法通过默认的映射关系对应起来&#xff0c;就需要指定 属性名 对应 的 字段名。 官网示例 代码实例 package com.example.web.…

js 实现删除数组指定元素

文章目录 需求分析1. 使用 splice() 方法2. 使用 filter() 方法3. 使用 splice 和展开运算符&#xff08;ES6&#xff09;&#xff1a; 新的需求新的分析 需求 删除数组中的指定元素&#xff0c;阁下该如何应对 分析 有多种方法可以实现 JavaScript 数组删除指定元素。以下是其…

MATLAB算法实战应用案例精讲-【人工智能】机器人标定方法

目录 前言 算法原理 为什么机器人需要标定? 哪种情况不需要标定? 理论详解

【网络原理】初始网络,了解概念

文章目录 1. 网络通信1.1 局域网LAN1.2 广域网WAN 2. 基础概念2.1 IP2.2 端口号 3. 认识协议4. 五元组5. 协议分层5.1 分层的作用5.2 OSI七层模型5.3 TCP/IP五层&#xff08;四层&#xff09;模型 6. 封装和分用 1. 网络通信 计算机与计算机之间是互相独立&#xff0c;是独立模…

【小沐学前端】Node.js实现UDP和Protobuf 通信(protobuf.js)

文章目录 1、简介1.1 node1.2 Protobuf 2、下载和安装2.1 node2.2 Protobuf 3、node 代码示例3.1 HTTP3.2 UDP单播3.4 UDP广播 4、Protobuf 代码示例4.1 例子:awesome.proto 结语 1、简介 1.1 node Node.js 是一个开源的、跨平台的 JavaScript 运行时环境。 Node.js 是一个开源…

Z检验scipy.stats.norm的相关计算

Z检验&#xff08;Z-test&#xff09;是一种用于检验一个样本的均值是否与已知的总体均值相等的统计方法。它通常用于以下情况&#xff1a; 总体参数已知&#xff1a; 当总体的均值和标准差已知时&#xff0c;可以使用Z检验来确定样本均值是否与总体均值相等。 大样本&#xff…

Leetcode---364场周赛

题目列表 2864. 最大二进制奇数 2865. 美丽塔 I 2866. 美丽塔 II 2867. 统计树中的合法路径数目 一、最大二进制奇数 这题只要你对二进制有了解(学编程的不会不了解二进制吧)&#xff0c;应该问题不大&#xff0c;这题要求最大奇数&#xff0c;1.奇数&#xff1a;只要保证…

数据结构 | 二叉树

基本形状 可参照 数据结构&#xff1a;树(Tree)【详解】_数据结构 树_UniqueUnit的博客-CSDN博客 二叉树的性质 三种顺序遍历

区块链实验室(26) - 区块链期刊Blockchain: Research and Applications

Elsevier出版物“Blockchain: Research and Applications”是浙江大学编审的期刊。该期刊自2020年创刊&#xff0c;并出版第1卷。每年出版4期&#xff0c;最新期是第4卷第3期(2023年9月)。 目前没有官方的IF&#xff0c;Elsevier的引用因子Citescore是6.4。 虽然是新刊&#xf…

Android studio升级Giraffe | 2022.3.1 Patch 1踩坑

这里写自定义目录标题 not "opens java.io" to unnamed module错误报错信息解决 superclass access check failed: class butterknife.compiler.ButterKnifeProcessor$RScanner报错报错信息解决 Android studio升级Giraffe | 2022.3.1 Patch 1后&#xff0c;出现项目…

ElementUI之CUD+表单验证

目录 前言&#xff1a; 增删改查 表单验证 前言&#xff1a; 继上篇博客来写我们的增删改以及表单验证 增删改查 首先先定义接口 数据样式&#xff0c;我们可以去elementUI官网去copy我们喜欢的样式 <!-- 编辑窗体 --><el-dialog :title"title" :visib…

MT8385 Android AB分区系统升级(命令模式)

AB系统分区升级使用的是update_engine,RecoverySystem 只适用于单分区的系统升级 1.解压开update.zip 可以查看到palyload的属性 2.使用ADB命令update_engine_client即可对AB分区进行升级 使用adb shell 命令进行升级 update_engine_client --payload xxx --update --hea…

Qt扩展-QCustomPlot绘图基础概述

QCustomPlot绘图基础概述 一、概述二、改变外观1. Graph 类型2. Axis 坐标轴3. 网格 三、案例1. 简单布局两个图2. 绘图与多个轴和更先进的样式3. 绘制日期和时间数据 四、其他Graph&#xff1a;曲线&#xff0c;条形图&#xff0c;统计框图&#xff0c;… 一、概述 本教程使用…

Error: node: unknown or unsupported macOS version: :dunno 错误解决

一、原因 今天安装 brew install node报错了&#xff0c;错误信息如下&#xff1a; 二、解决方案 1&#xff09;查找homebrew-cask安装位置 echo $(brew --repo homebrew/homebrew-cask) // 输出 /opt/homebrew/Library/Taps/homebrew/homebrew-cask2&#xff09;使用 gi…

linux 查看CPU架构是AMD还是ARM

要查看 Linux 系统的 CPU 架构是 AMD 还是 ARM&#xff0c;可以使用以下命令&#xff1a; 使用 lscpu 命令并查找 Architecture 字段&#xff1a; lscpu | grep Architecture如果输出结果中包含 x86_64 或 i686&#xff0c;则表示系统的 CPU 架构是 AMD&#xff08;或者是 x86…

wxWidgets(1):在Ubuntu 环境中搭建wxWidgets 库环境,安装库和CodeBlocks的IDE,可以运行demo界面了,继续学习中

1&#xff0c;选择使用 wxWidgets 框架 选择这个主要是因为完全的开源&#xff0c;不想折腾 Qt的库&#xff0c;而且打包的文件比较大。 网络上面有很多的对比&#xff0c;而且使用QT的人比较多。 但是我觉得wxwidgets 更加偏向 c 语法本身&#xff0c;也有助学习C。 没有太多…

Java安全之servlet内存马分析

目录 前言 什么是中间键 了解jsp的本质 理解servlet运行机制 servlet的生命周期 Tomcat总体架构 查看Context 的源码 servlet内存马实现 参考 前言 php和jsp一句话马我想大家都知道&#xff0c;早先就听小伙伴说过一句话木马已经过时了&#xff0c;现在是内存马的天下…

centos7下根目录扩容

起因 系统盘给了800G 新人装的系统&#xff0c;根目录/只给了50G&#xff0c;home目录给750G&#xff0c;真是头疼&#xff0c;还没干啥&#xff0c;根目录就快满了 没辙&#xff0c;趁安装的内容还不多&#xff0c;自己扩容吧 结果&#xff0c;把根目录扩到800G 空间都分完了…

Snapdragon Profiler分析Android GPU

Snapdragon Profiler&#xff08;骁龙分析器&#xff09;是一款性能分析软件&#xff0c;在Windows、 Mac、和 Linux平台上都可以运行&#xff0c;主要是用来分析使用了高通骁龙处理器的Android设备。 Snapdragon Profiler通过USB连接这些Android设备&#xff0c;开发者可以用…