string的模拟实现与深浅拷贝

在上一章中可以看见,string类函数的基本实现和用法,在本文。来用基础的语言来模拟实现string类,来了解一下他们的基础底层;

在VS中string,我们可以看见,实现VS的类成员很多,很麻烦;

 我们自己实现为了基础理解底层时,可以把成员设的简单点;只设 char*  size  和 capacity

在实现一些成员函数时

注意事项:

防止权限扩大

要根据string函数的具体要求去实现,不要忘了实现const类型,防止权限扩大;

注意只是两个接口;一个可读可写的[ ],一个只能读的不能写的[ ]。

string输入流

std::cin 的输入 ,自动会将 空格(’ ‘) ,等认为换行符;这样在实现,string的输入流时,会导致无法输入 像we are famliy 的字符;如此就要请出 getline,这个可以自己实现换行符 是什么的std函数。 

深浅拷贝问题

因此,这里要记得为string写深拷贝,编译器自己实现的浅拷贝无法实现;

增加扩容效率

以substr为例子,可以选择直接 += 但这样会导致经常扩容,效率低;但这里能提前知道了内存大小,可以提前扩容,增加效率 

隐式类型转换

因为 _size  的类型是size 无 符号,如果将end设为int类型,如果情况是pos = 0,在减到 - 1时 进行类似类型转换,int 转为 size_t ;-1 无符号的反义码是11111111 11111111 很大;导致无限循环;

或者 换一个 循环 不访问 -1 的也行; 但最好保证类型一致;

字符串 最后存在“ \0 ”

字符串最后的"\0"存在 ,可以移动过去,要注意;

对这里提醒一下,对于这种移动数据的插入,最好少用,效率太低了,注意尽量少用,虽然很方便

    注意域限定:

海滩std的模板函数 swap 

但要注意这个std::swap,虽然存在模板,可以任意转换但是,转换中却有拷贝构造,和运算符重载,效率很低;但是方便也是确实的

参考代码

string.h 

#pragma once#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
//#include<string>
#include<assert.h>
using namespace std;namespace xryq {class string {public:typedef char* iterator;typedef const char* const_iterator;iterator begin(){return _str;}iterator end(){return _str + _size;}const_iterator begin() const{return _str;}const_iterator end() const{return _str + _size;}//string()//	:_str(new char[1]{ '\0' })//	,_size(0)//	,_capacity(0)//{}string(const string& s){_str = new char[s._capacity + 1];strcpy(_str, s._str);_capacity = s._capacity;_size = s._size;}//现代写法string(const string& s){string tmp(s._str);swap(s); }//构造函数重载//string(const char* str = '\0')string(const char* str = ""){_size = strlen(str);_capacity = _size;_str = new char[_capacity + 1];strcpy(_str, str);}~string(){delete[] _str;_size = _capacity = 0;}const char& operator[](size_t pos) const{assert(pos < _size);return _str[pos];}char& operator[](size_t pos){assert(pos < _size);return _str[pos];}const char* c_str() const{return _str;}const size_t capacity() const{return _capacity;}const size_t size() const {return _size;}void clear(){//编译器 遇到 \0 就失效 在前面加 \0相当于清除_str[0] = '\0';//_capacity = _size = 0;//容量没有清 只是  数量变了_size = 0;}void swap(string s){std::swap(_str, s._str);std::swap(_size, s._size);std::swap(_capacity, s._capacity);}// 现代写法string& operator=(const string s){if (this != &s){swap(s);return *this;}}//末代写法//string& operator=(const string& s)//{//	if (this != &s)//	{		//		//这里先清除的主要原因是  更方便 且不会有内容浪费  等问题//		delete[] _str;//		_str = new char[s._capacity + 1];//		_capacity = s._capacity;//		_size = s._size;//	}//}void reserve(size_t n);void push_back(char ch);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, size_t len = npos);size_t find(char ch, size_t pos = 0);size_t find(const char* str, size_t pos = 0);string substr(size_t pos = 0, size_t len = npos);//static const size_t npos = -1;  这里可以 或者 只能看成 c++ 对 整形的绿色通道//static const double i = 1.1;  只有整形不报错private:char* _str;size_t _size;size_t _capacity;static const size_t npos = -1;};void text_string1();void text_string2();bool operator<(const string& s1, const string& s2);bool operator<=(const string& s1, const string& s2);bool operator>(const string& s1, const string& s2);bool operator>=(const string& s1, const string& s2);bool operator==(const string& s1, const string& s2);bool operator!=(const string& s1, const string& s2);ostream& operator<<(ostream& out, const string& s);istream& operator>>(istream& in, string& s);}

string.cpp


#include"string.h"namespace xryq{//static const size_t npos = -1;void string::reserve(size_t n){assert(n > _capacity);cout << n << endl;char* tmp = new char[n + 1];_capacity = n;strcpy(tmp, _str);_str = tmp;}void string::push_back(char ch){if (_capacity == _size){reserve(_capacity == 0 ? 4 : _capacity * 2);}_str[_size] = ch;_size++;}string& string::operator+=(char ch){push_back(ch);return *this;}string& string::operator+=(const char* str){append(str);return *this;}void string::append(const char* str){size_t len = strlen(str);if(_size + len > _capacity)reserve(_size + len > _capacity * 2 ? _size + len : _capacity * 2);strcpy(_str + _size, str);_size += len;}void string::insert(size_t pos, char ch){assert(pos <= _size);if (_size == _capacity){reserve(_capacity == 0 ? 4 : _capacity * 2);}size_t end = _size;//int end = _size + 1;//这是c语言 留下来的一个坑;如果比较时 类型不一样那么就会 //进行隐式类型转换   小向大 的转换  int 向 unsign的转换while (end >= pos){_str[end + 1] = _str[end];--end;}_str[end] = ch;++_size;//或者 不访问-1也许//while (end > pos)//{//	_str[end] = _str[end - 1];//	--end;//}//_str[end] = ch;//++_size;}void string::insert(size_t pos, const char* str){assert(pos <= _size);size_t len = strlen(str);if (_size + len > _capacity){reserve(_size + len > _capacity * 2 ? _size + len : _capacity * 2);}size_t end = _size + len;while (end > pos + len - 1){_str[end] = _str[end - len];--end;}for (int i = 0; i < len; ++i){_str[pos + i] = str[i];}_size += len;}void string::erase(size_t pos, size_t len){assert(pos < _size);if (len >= _size - pos){_str[pos] = '\0';_size = pos;}else {//for (size_t i = 0; i < _size - pos - 1 - len; ++i)//{//	_str[pos + i] = _str[pos + len + i];//}//_str[_size - 1 - len] = '\0';//最后一个字符是\0for (size_t i = 0; i <= _size - pos - len; ++i){_str[pos + i] = _str[pos + len + i];}_size -= len;}}size_t string::find(char ch, size_t pos){assert(pos < _size);for (size_t i = pos; i < _size; i++){if (_str[i] == ch){return i;}}return npos;}size_t string::find(const char* str, size_t pos){assert(pos < _size);const char* ch = strstr(_str, str);for (size_t i = pos; i < _size; ++i){if (_str[i] = *ch){return i;}}return npos;}string string::substr(size_t pos, size_t len){assert(pos < _size);string tmp;if (_size - pos <= len){len = _size - pos;}//提前算好空间 提高效率tmp.reserve(len);for (size_t i = 0; i <= len; ++i){tmp += _str[i + pos];}return tmp;}ostream& operator<<(ostream& out, const string& s){for (auto i : s){out << i;}//cout << s.c_str();return out;}istream& operator>>(istream& in, string& s){s.clear();char ch;ch = in.get();while (ch != ' ' && ch != '\n'){s += ch;ch = in.get();}return in;}//上面的牵扯到 多次扩容  效率比较低//istream& operator>>(istream& in, string& s)//{//	s.clear();//	char ch;//	const int N = 256;//	char buff[N];//	int i = 0;//	ch = in.get();//	while (ch != ' ' && ch != '\n')//	{//		buff[i] = ch;//		i++;//		if (i == N - 1)//		{//			buff[i] = '\0';//			s += buff;//			i = 0;//		}//		ch = in.get();//	}//	if (i > 0)//	{//		buff[i] = '\0';//		s += buff;//	}//	return in;//}}

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

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

相关文章

【STM32】电容触摸按键

电容按键就是酷&#xff0c;但据我使用过电容按键版的洗澡计费机子后&#xff0c;一生黑&#xff08;湿手优化没做好的电容按键简直稀碎&#xff09;。 大部分图片来源&#xff1a;正点原子HAL库课程 专栏目录&#xff1a;记录自己的嵌入式学习之路-CSDN博客 目录 1 触摸按…

Zookeeper官网Java示例代码解读(一)

2024-08-22 1. 基本信息 官网地址&#xff1a; https://zookeeper.apache.org/doc/r3.8.4/javaExample.html 示例设计思路 Conventionally, ZooKeeper applications are broken into two units, one which maintains the connection, and the other which monitors data. I…

【C++ Primer Plus习题】7.5

问题: 解答: #include <iostream> using namespace std;int function(int n) {if (n 0)return 1;if (n 1)return 1;return n* function(n - 1); }int main() {int value 0;while (true){cout << "请输入数字:";cin >> value;cout << val…

华为Huawei路由器交换机SSH配置

华为设备的SSH登录配置需要5个步骤&#xff0c;示例如下&#xff1a; 一、配置命令 使能SSH功能 stelnet server enable生成公钥 rsa local-key-pair create 1024配置AAA用户密码及相应授权 aaalocal-user xxx password cipher xxxyyy1234local-user xxx privilege level …

ADB 获取屏幕坐标,并模拟滑动和点击屏幕

本文声明:本文是参考https://blog.csdn.net/beyond702/article/details/69258932编制。同时,补充了在windows系统模式下,详细的获取屏幕坐标的步骤。 1.判断设备与windows电脑USB连接是否正常 在CMD窗口输入命令:ADB devices,按ENTER键,输出如下结果,则表示连接正常。 …

Prometheus+Grafana监控数据可视化

上一篇文章讲了prometheus的简单使用&#xff0c;这一篇就先跳过中间略显枯燥的内容&#xff0c;来到监控数据可视化。 一方面&#xff0c;可视化的界面看着更带劲&#xff0c;另一方面&#xff0c;也更方便我们直观的查看监控数据&#xff0c;方便后面的学习。 Grafana安装与…

DIFFUSION 系列笔记| Latent Diffusion Model、Stable Diffusion基础概念、数学原理、代码分析、案例展示

目录 Latent Diffusion Model LDM 主要思想 LDM使用示例 LDM Pipeline LDM 中的 UNET 准备时间步 time steps 预处理阶段 pre-process 下采样过程 down sampling 中间处理 mid processing 上采样 upsampling 后处理 post-process LDM Super Resolution Pipeline…

Redis基本全局命令

文章目录 get和setkeysexistsdelexpirettltype redis全局命令&#xff1a; redis支持很多种数据结构&#xff0c;整体上来说。redis是键值对结构&#xff0c;key固定就是字符串&#xff0c;value实际上就会有很多种&#xff0c;比如说&#xff1a; 字符串哈希表列表有序集合 …

住宅物业满意度计算方式中满意率和满意度指数的区别

满意率和满意度指数是用于计算住宅物业满意度的两种不同方式&#xff0c;它们的区别如下&#xff1a; 1、满意率&#xff1a;满意率是通过计算满意的居民人数与总参与调查的居民人数之间的比例来衡量满意度。它以百分比形式表示&#xff0c;可以直观地了解居民对物业管理的整体…

集运系统如何多维度展现企业业务情况?

在集运行业&#xff0c;数据是企业决策的重要依据。为了在竞争中保持优势&#xff0c;企业需要一套高效、灵活且可靠的管理工具来应对市场的快速变化。易境通集运系统以其全面而精细的统计报表功能&#xff0c;成为企业决策优化和业务增长的重要助手。 易境通集运系统https://…

使用在AMD GPU上运行的ROCm进行大语言模型的自然语言处理任务

Performing natural language processing tasks with LLMs on ROCm running on AMD GPUs — ROCm Blogs 在这篇博客中&#xff0c;您将学习如何使用在AMD的Instinct GPU上运行的ROCm进行一系列流行且有用的自然语言处理&#xff08;NLP&#xff09;任务&#xff0c;使用不同的大…

新手该如何选择与小程序定位相关的关键词

关键词的优化是提高小程序排名的关键步骤之一&#xff0c;所以如何选择与小程序定位相关的关键词是一个很重要的过程&#xff0c;需要考虑多个因素以确保关键词既符合小程序的业务特性&#xff0c;又能吸引目标用户。以下是一些具体的步骤和建议&#xff1a; 1. 深入了解小程序…

Go发布自定义包

1、初始化go.mod go mod init github.com/xumeng03/images2、编写包内容 这里只是一个简单的压缩jpg/jpeg图片例子&#xff0c;代码参考 https://github.com/disintegration/imaging 2.1、fs.go package imagesimport ("image""io""os""p…

Vue3中的defineExpose的认识

文章目录 defineExpose子组件父组件&#xff1a;总结&#xff1a; defineExpose 使用 <script setup> 的组件是默认关闭的——即通过模板引用或者 $parent 链获取到的组件的公开实例&#xff0c;** 不会 **暴露任何在 <script setup> 中声明的绑定。 可以通过 def…

OpenCV几何图像变换(10)透视变换函数warpPerspective()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 warpPerspective 函数使用指定的矩阵对源图像进行透视变换&#xff1a; dst ( x , y ) src ( M 11 x M 12 y M 13 M 31 x M 32 y M 33 , M…

必备工具:2024四大视频压缩神器推荐!

随着视频质量的不断提高&#xff0c;文件大小也变得越来越大&#xff0c;这给存储和分享带来了不小的挑战。今天&#xff0c;我们就来一起探索几款优秀的视频压缩工具&#xff01; 福昕视频压缩大师 直达链接&#xff1a;www.foxitsoftware.cn/shipinyasuo/ 福昕视频压缩大师…

两个月冲刺软考——SQL基础:排序、分组和聚合函数的实用指南

1.涉及到的部分基本语法 1.1 ORDER BY 与 GROUP BY ORDER BY用于对查询结果进行排序&#xff1b;默认是升序&#xff08;ASC&#xff09;&#xff0c;可以指定降序&#xff08;DESC&#xff09;。 GROUP BY用于将数据按照一个或多个列进行分组&#xff1b;通常与聚合函数&am…

长视频平台:谁都想成为「爆款制造机」

【潮汐商业评论/ 原创】 “今晚下班回家&#xff0c;我要先追优酷更新的《边水往事》&#xff0c;再补爱奇艺的《九部检察官》&#xff0c;还有腾讯视频新上线的脱口秀……”对于Chloe来说&#xff0c;没有什么比下班回家看剧更放松的。 “为了追这些剧&#xff0c;我最近把优…

苹果秋季发布会前瞻:iPhone 16领衔新品盛宴

苹果定档9月9日&#xff0c;揭开新品神秘面纱 苹果公司近日正式宣布&#xff0c;将于9月9日在加州库比蒂诺的Apple Park&#xff0c;史蒂夫乔布斯剧院举办年度秋季新品发布会&#xff0c;主题为“It’s Glowtime”&#xff0c;预示着Siri界面将迎来一场华丽变身。此次发布会较原…

米壳AI:发现一个可以保存国内外视频的宝藏网站!

&#x1f388;嘿&#xff0c;朋友们&#xff01;今天我要给大家分享一个超级棒的发现 —— 一个可以下载国内外视频的网站&#xff01;&#x1f389; 在这个信息爆炸的时代&#xff0c;我们总是渴望能够随时随地欣赏到精彩的视频内容。 无论是国内的热门影视剧、搞笑短视频&am…