【C++课程学习】:string的模拟实现
🎁个人主页:我们的五年
🔍系列专栏:C++课程学习
🎉欢迎大家点赞👍评论📝收藏⭐文章
目录
一.string的主体框架:
二.string的分析:
🍔构造函数和析构函数:
🍔迭代器:
🍔赋值运算符重载:
🍔空间扩容:
🍔尾插:
🍔获取_str,_capacity,_size:
🍔[]重载,随机访问:
🍔在结尾追加字符串
🍔在指定位置插入和删除字符串:
🍔交换:
🍔获取子串和寻找元素和字符串:
🍔运算符重载:
🍔流插入和流提取重载:
通过对string的模拟实现,可以对string有更深的理解和认识,大概知道底层的逻辑,以后出现什么问题可以更好的解决。对学习以后的容器也有很大的帮助。
一.string的主体框架:
1.迭代器 2.运算符重载 3.
#define _CRT_SECURE_NO_WARNINGS 1
#pragma once
#include<iostream>
#include<cstring>
#include<assert.h>
#include<algorithm>using namespace std;namespace bit {class string {public://迭代器typedef char* iterator;typedef const char* const_iterator;iterator begin();const_iterator begin()const;iterator end();const_iterator end()const;//构造函数string(size_t capacity = 4);string(const string& s);string(const char* str);string& operator=(const string& str);//析构函数~string();//异地扩容void reserve(size_t newcapacity);//尾插数据void push_back(char c);const char* c_str()const;size_t size()const;size_t capacity()const;char& operator[](size_t pos);const char& operator[](size_t pos)const;void append(const char* str);string& operator+=(char ch);string& operator+=(const char* str);void insert(size_t pos, char ch);void insert(size_t pos, const char* str);void erase(size_t pos = 0, size_t len = npos);void swap(string& s);string substr(size_t pos = 0, size_t len = npos);size_t find(char ch, size_t pos = 0);size_t find(const char* str, size_t pos = 0);//运算符重载bool operator<(const string& s) const;bool operator>(const string& s) const;bool operator<=(const string& s) const;bool operator>=(const string& s) const;bool operator==(const string& s) const;bool operator!=(const string& s) const;//对sring进行清理void clear();private:const static size_t npos = -1;char* _str;//有效大小size_t _size;//空间的容量size_t _capacity;};//重载流插入和流提取istream& operator>> (istream& is, string& str);ostream& operator<< (ostream& os, const string& str);
}
二.string的分析:
🍔构造函数和析构函数:
构造函数常用的是三个,普通构造,拷贝构造,用const char*类型进行构造。
//capacity表示要提前开的空间大小string::string(size_t capacity):_str(new char[capacity + 1]), _capacity(capacity), _size(0){_str[0] = '\0';}//拷贝构造string::string(const string& s){_capacity = s._capacity;_size = s._size;_str = new char[_capacity + 1];strcpy(_str, s._str);}string::string(const char* str){size_t length = strlen(str);_str = new char[length + 1];_capacity = _size = length;strcpy(_str, str);}string::~string(){delete[] _str;_str = nullptr;_capacity = _size = 0;}
🍔迭代器:
//迭代器typedef char* iterator;typedef const char* const_iterator;iterator begin();const_iterator begin()const;iterator end();const_iterator end()const;
🍔赋值运算符重载:
string& string::operator=(const string& str){if (str._capacity > _capacity)reserve(str._capacity);strcpy(_str, str._str);return *this;}
🍔空间扩容:
void string::reserve(size_t newcapacity){//先判断是否需要扩容//如果newcapacity小于等于,就不会扩,也不会缩容if (newcapacity <= _capacity)return;char* p = new char[newcapacity + 1];_capacity = newcapacity;strcpy(p, _str);delete[] _str;_str = p;}
🍔尾插:
void string::push_back(char c){if (_size == _capacity){//不能直接乘以两倍,_capacity可能为0,乘二还是为0size_t newcapacity = _capacity == 0 ? 4 : _capacity * 2;reserve(newcapacity);}_str[_size] = c;_size++;}
🍔获取_str,_capacity,_size:
const char* string:: c_str()const{return _str;}size_t string::size()const{return _size;}size_t string::capacity()const{return _capacity;}
🍔[]重载,随机访问:
char& string::operator[](size_t pos){assert(pos >= 0 && pos < _size);return _str[pos];}const char& string::operator[](size_t pos)const{assert(pos >= 0 && pos < _size);return _str[pos];}
🍔在结尾追加字符串
void string::append(const char* s){size_t length = strlen(s);if(_size + length > _capacity)reserve(_size + length);//strcat(_str, s);_size += length;}
🍔在指定位置插入和删除字符串:
void string::insert(size_t pos, char ch){assert(pos >= 0 && pos <= _size);if (_size == _capacity)reserve(_capacity * 2);size_t end = _size + 1;while (end > pos){_str[end] = _str[end - 1];end--;}_size++;_str[pos] = ch;}void string::insert(size_t pos, const char* str){assert(pos >= 0 && pos <= _size);size_t length = strlen(str);if (length + _size > _capacity)reserve(length + _size);for (size_t i = _size - 1; i >= pos; i--)_str[i + length] = _str[i];_str[_size + length] = 0;for (size_t i = 0; i < length; i++)_str[i + pos] = str[i];}void string::erase(size_t pos, size_t len){assert(pos >= 0 && pos < _size - 1);if (len>=_size-pos){_str[pos] = '\0';_size = pos;}else{strcpy(_str + pos, _str + pos + len);_size -= len;}}
🍔交换:
void string::swap(string& s){std::swap(s._capacity, _capacity);std::swap(s._size, _size);std::swap(s._str, _str);}
🍔获取子串和寻找元素和字符串:
string string::substr(size_t pos, size_t len){assert(pos >= 0 && pos < _size);if (len > _size - pos){bit::string substr(_str + pos);return substr;}else{bit::string substr(len);for (size_t i = pos; i < pos+len; i++)substr += _str[i];return substr;}}size_t string::find(char ch, size_t pos){for (size_t i = 0; i < pos; i++){if (_str[i] == ch)return i;}return -1;}size_t string::find(const char* str, size_t pos){char* p = strstr(_str + pos, str);return p - _str;}
🍔运算符重载:
bool string::operator<(const string& s) const{return strcmp(_str, s._str)<0;}bool string::operator>(const string& s) const{return !((*this) <= s);}bool string::operator<=(const string& s) const{return ((*this) < s || (*this) == s);}bool string::operator>=(const string& s) const{return ((*this) > s || (*this) == s);}bool string::operator==(const string& s) const{return strcmp(_str, s._str) == 0;}bool string::operator!=(const string& s) const{return !((*this) == s);}string& string::operator+=(char ch){insert(_size, ch);return *this;}string& string::operator+=(const char* str){insert(_size, str);return *this;}
🍔流插入和流提取重载:
istream& operator>>(istream& is, string& s){s.clear();char it = is.get();while (it != ' ' && it != '\n'){s += it;it = is.get();}return is;}ostream& operator<<(ostream& os, const string& s){for (size_t i = 0; i < s.size(); i++)os << s[i];return os;}
相关文章:

【C++课程学习】:string的模拟实现
🎁个人主页:我们的五年 🔍系列专栏:C课程学习 🎉欢迎大家点赞👍评论📝收藏⭐文章 目录 一.string的主体框架: 二.string的分析: 🍔构造函数和析构函数&a…...

Linux(VMware + CentOS )设置固定ip
需求:设置ip为 192.168.88.130 先关闭虚拟机 启动虚拟机 查看当前自动获取的ip 使用 FinalShell 通过 ssh 服务远程登录系统,更换到 root 用户 修改ip配置文件 vim /etc/sysconfig/network-scripts/ifcfg-ens33 重启网卡 systemctl restart network …...

安卓 android studio各版本下载地址(官方)
https://developer.android.google.cn/studio/archive 别用中文,右上角的语言切换成英文...

如何在一个 Docker 容器中运行多个进程 ?
在容器化的世界里,Docker 彻底改变了开发人员构建、发布和运行应用程序的方式。Docker 容器封装了运行应用程序所需的所有依赖项,使其易于跨不同环境一致地部署。然而,在单个 Docker 容器中管理多个进程可能具有挑战性,这就是 Sup…...

poetry 配置多个cuda环境心得
操作系统:ubuntu22.04 LTS python版本:3.12.7 最近学习了用poetry配置python虚拟环境,当为不同的项目配置cuda时,会遇到不同的项目使用的cuda版本不一致的情况。 像torch 这样的库,它们会对cuda-toolkit有依赖&…...

网络编程入门
目录 1.网络编程入门 1.1 网络编程概述【理解】 1.2 网络编程三要素【理解】 1.3 IP地址【理解】 1.4InetAddress【应用】 1.5端口和协议【理解】 2.UDP通信程序 2.1 UDP发送数据【应用】 2.2UDP接收数据【应用】 2.3UDP通信程序练习【应用】 3.TCP通信程序 3.1TCP…...

Linux-socket详解
Linux-socket详解_socket linux-CSDN博客...

SQL Server 2022安装要求(硬件、软件、操作系统等)
SQL Server 2022安装要求 1、硬件要求2、软件要求3、操作系统支持4、Server Core 支持5、跨语言支持6、磁盘空间要求 1、硬件要求 以下内存和处理器要求适用于所有版本的 SQL Server: 组件要求存储SQL Server 要求最少 6 GB 的可用硬盘驱动器空间。 磁盘空间要求随…...

“众店模式”:创新驱动下的商业新生态
在数字化浪潮的推动下,传统商业模式正经历着前所未有的转型。“众店模式”作为一种新兴的商业模式,以其独特的商业逻辑和创新的玩法,为商家和消费者构建了一个共赢的商业新生态。 一、“众店模式”的核心构成 “众店模式”的成功࿰…...

54. 螺旋矩阵
https://leetcode.cn/problems/spiral-matrix/description/?envTypestudy-plan-v2&envIdtop-100-liked观察示例中的输出轨迹我们可以想到如下设计: 1.在朝某一方向行进到头后的改变方向是确定的,左->下,下->右,右->…...

剧本杀小程序,市场发展下的新机遇
剧本杀作为休闲娱乐的一种游戏方式,在短时间内进入了大众视野中,受到了广泛关注。近几年,剧本杀行业面临着创新挑战,商家需求寻求新的发展机遇,在市场饱和度下降的趋势下,获得市场份额。 随着科技的不断进…...

【系统架构设计师】论文:论基于 ABSD 的软件开发
更多内容请见: 备考系统架构设计师-专栏介绍和目录 文章目录 摘要正文摘要 2022年5月,我就职的公司承接了xx的智慧党建工作,建设“党建红云” 系统,为xx公司的党组织提供觉务管理、服务功能,促进党员学习和党组织交流。我在该项目中承担架构设计师的职责,主导需求分析和…...

为什么OLED透明屏在同类产品中显示效果最好
说起OLED透明屏,这家伙在同类产品里那真的是“一枝独秀”啊!为啥这么说呢?且听我细细道来。 首先,OLED透明屏的透明度那是杠杠的!它不像传统显示屏那样有个固定的背景,而是可以实现像素级的透明效果。这样一…...

深度学习基础知识-Batch Normalization(BN)超详细解析
一、背景和问题定义 在深层神经网络(Deep Neural Networks, DNNs)中,层与层之间的输入分布会随着参数更新不断发生变化,这种现象被称为内部协变量偏移(Internal Covariate Shift)。具体来说,由…...

基于单片机的燃气报警阀门系统
本设计基于单片机的燃气报警阀门系统,燃气报警阀门系统采用STM32主控制器为核心芯片,外围电路由燃气传感器、OLED液晶显示模块、按键模块、蜂鸣器报警模块、电磁阀以及SIM800模块等模块组成。燃气传感器模块负责采集燃气浓度数据,采集完成由S…...

watch与computed的区别、运用的场景
computed和watch都是响应式数据变化的重要机制,但它们在功能、使用场景和性能表现上有显著的区别。 主要区别 功能和用途 1、computed:计算属性,用于基于其他数据属性进行计算,并返回一个结果。它具有缓存机制,只有当…...

【ESP32+MicroPython】开发环境部署
本教程将指导你如何在Visual Studio Code(VSCode)中设置ESP32的MicroPython开发环境。我们将涵盖从安装Python到烧录MicroPython固件的整个过程,以及如何配置VSCode以便与ESP32进行交互。 准备工作 安装Python 确保你的计算机上安装了Pyth…...

Vision - 开源视觉分割算法框架 Grounded SAM2 配置与推理 教程 (1)
欢迎关注我的CSDN:https://spike.blog.csdn.net/ 本文地址:https://spike.blog.csdn.net/article/details/143388189 免责声明:本文来源于个人知识与公开资料,仅用于学术交流,欢迎讨论,不支持转载。 Ground…...

DAY21|二叉树Part08|LeetCode: 669. 修剪二叉搜索树、108.将有序数组转换为二叉搜索树、538.把二叉搜索树转换为累加树
目录 LeetCode: 669. 修剪二叉搜索树 基本思路 C代码 LeetCode: 108.将有序数组转换为二叉搜索树 基本思路 C代码 LeetCode: 538.把二叉搜索树转换为累加树 基本思路 C代码 LeetCode: 669. 修剪二叉搜索树 力扣代码链接 文字讲解:LeetCode: 669. 修剪二叉搜…...

在gitlab,把新分支替换成master分支
1、备份master分支,可以打tag 2、删除master分支 正常情况下,master分支不允许删除,需要做两个操作才能删除 a、变更项目默认分支为非master分支,可以先随便选择 b、取消master为非保护分支 操作了上述两步,就可以删…...

使用 Spring Boot 集成 Thymeleaf 和 Flying Saucer 实现 PDF 导出
在 Spring Boot 项目中,生成 PDF 报表或发票是常见需求。本文将介绍如何使用 Spring Boot 集成 Thymeleaf 模板引擎和 Flying Saucer 实现 PDF 导出,并提供详细的代码实现和常见问题解决方案。 目录 一、项目依赖二、创建 Thymeleaf 模板三、创建 PDF 生…...

web——upload1——攻防世界
第一次做木马题目,有点懵逼,浮现一下做题思路 可以上传一个文件,通过学习学习到了一句话木马 一句话木马: 利用文件上传漏洞,往目标网站中上传一句话木马,然后你就可以在本地通过中国菜刀chopper.exe即可…...

nginx 搭建网站
1.查看防火墙状态systemctl status firewalld 2.getenforce 3.安装nginx yum install nginx -y 4.网站信息 echo "welcome to yinchuankejixuanyuan" > /usr/share/nginx/html/index.html 5.查看命令状态 nginx -t 6.重启 systemctl restart nginx...

Java基础-Java中的常用类(上)
(创作不易,感谢有你,你的支持,就是我前行的最大动力,如果看完对你有帮助,请留下您的足迹) 目录 String类 创建字符串 字符串长度 连接字符串 创建格式化字符串 String 方法 System类 常用方法 方…...

气压仪器智能打气泵方案芯片SIC8833
智能打气泵方案最开始是机械式的开发,后来慢慢地演变成由一个气缸、压力传感器和主控芯片的开发的PCBA方案,它具备小体积、智能数显、预设胎压、动态测量、精准压力检测以及过充过放等功能。 其方案设计原理是利用主控芯片和压力传感器的组合设计&#x…...

软件测试(系统测试)的定位和专业:完善产品;专业;非助手;自动化
软件测试(系统测试)的定位 在研发流程的后端,测试并非无中生有的创举,而是从既有基础(即“1”)出发,致力于推动产品向更高层次(即从“1”到“100”)的跃升与完善。在这一…...

2024 CSS保姆级教程四
CSS中的动画 CSS动画(CSS Animations)是为层叠样式表建议的允许可扩展标记语言(XML)元素使用CSS的动画的模块 即指元素从一种样式逐渐过渡为另一种样式的过程 常见的动画效果有很多,如平移、旋转、缩放等等&#…...

PostgreSQL技术内幕17:PG分区表
文章目录 0.简介1.概念介绍2.分区表技术产生的背景3.分区类型及使用方式4.实现原理4.1 分区表创建4.2 分区表查询4.3 分区表写入4.4 分区表删除 0.简介 本文主要介绍PG中分区表的概念,产生分区表技术的原因,使用方式和其内部实现原理,旨在能…...

群控系统服务端开发模式-应用开发-上传工厂开发
现在的文件、图片等上传基本都在使用oss存储。而现在常用的oss存储有阿里云、腾讯云、七牛云、华为云等,但是用的最多的还是前三种。而我主要封装的是本地存储、阿里云存储、腾讯云存储、七牛云存储。废话不多说,直接上传设计图及说明,就一目…...

【Docker系列】指定系统平台拉取 openjdk:8 镜像
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...