(C++)string模拟实现

string底层是一个是字符数组

为了跟库里的string区别,所以定义一个命名空间将类string包含

一、构造

1.构造函数

注意:将char*传给const char*是范围缩小,因此只能1:1构造一个

strlen遇到nullptr解引用会报错,因此缺省参数只能设置为" "

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

2.拷贝构造

深拷贝:重新开辟一个空间

浅拷贝(值拷贝):拷贝一个指针,指向同一片空间

string(const string& s):_size(s._size),_capacity(s._capacity)
{_str = new char[_capacity + 1];strcpy(_str, s._str);
}

3.析构

内置类型,调用默认成员函数,自定义类型调用默认构造

~string()
{if (_str != NULL){delete[] _str;_str = NULL;}_size = 0;_capacity = 0;
}

4.赋值

赋值运算符也是默认成员函数,如果不写会进行浅拷贝/值拷贝

string& operator=(const string& s)
{_size = s._size;_capacity = s._capacity;delete[] _str;_str = new char[_capacity+1];strcpy(_str, s._str);return *this;
}

二、迭代器

使用typedef 将用iterator代替char*

1.begin

iterator begin()
{return _str;
}

2.end

iterator end()
{return _str + _size;
}

三、修改

1.push_back

void push_back(char c)
{if (_size + 1 > _capacity){reserve(_size + 1);char* tmp = new char[_capacity + 1];strcpy(tmp, _str);delete[] _str;_str = tmp;}_str[_size] = c;_size++;_str[_size] = '\0';
}

2.+=

复用尾插

string& operator+=(char c)
{push_back(c);return *this;
}

3.append

通过reserve类似扩容的操作,扩大了字符串长度的空间,并且在原字符串‘\0’的位置上拷贝str字符串

void append(const char* str)
{size_t len = strlen(str);if (len + _size > _capacity){reserve(len + _size);char* tmp = new char[_capacity + 1];strcpy(tmp, _str);delete[] _str;_str = tmp;}strcpy(_str + _size, str);_size += len;
}

4.clear

void clear()
{_size = 0;_str[0] = '\0';
}

5.swap

void swap(T& a, T& b)
{T tmp = a;a = b;b = tmp;
}
void swap(string& s)
{bit::swap<char*>(_str, s._str);bit::swap<size_t>(_size, s._size);bit::swap<size_t>(_capacity, s._capacity);
}

6.c_str

const char* c_str()const
{const char* tmp = _str;return tmp;
}

四、容量

1.size

	size_t size()const{return _size;}

2.capacity

size_t capacity()const
{return _capacity;
}

3.empty

bool empty()const
{if (_size == 0){return true;}else{return false;}
}

4.resize

分三种情况

n<_size  删除数据

_size<n<_capacity 剩余空间初始化

n>_capacity 扩容+初始化

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

5.reserve

为防止new失败,所以使用临时变量tmp指向new出来的空间,若new成功,释放旧空间,并将—_str指向新的空间

void reserve(size_t n)
{if (n > _capacity){_capacity = n;char* tmp = new char[_capacity + 1];strcpy(tmp, _str);delete[]_str;_str = tmp;}
}

五、访问

1.[ ]

char& operator[](size_t index)
{return _str[index];
}
const char& operator[](size_t index)const
{return _str[index];
}

2."<,<=,>,>=,==,!="

通过strcmp,比较字符串从头开始字符的ASCII值,再通过复用来实现剩下的

const只能调用const,非const既可以调用非const,也可以调用const

bool operator<(const string& s)
{return (*this >= s);
}
bool operator<=(const string& s)
{return !(*this > s);
}
bool operator>(const string& s)
{return (strcmp(_str, s._str) > 0);
}
bool operator>=(const string& s)
{return (*this == s || *this > s);
}
bool operator==(const string& s)
{return strcmp(_str, s._str) == 0;
}
bool operator!=(const string& s)
{return !(*this==s);
}

3.find

size_t find(char c, size_t pos = 0)const
{while (pos < _size){if (_str[pos] == c){return pos;}pos++;}return npos;
}
size_t find(const char* s, size_t pos = 0)const
{const char* p = strstr(_str, s);if (p != nullptr){return _str - p;}return npos;
}

4.insert

注意size_t类型变量没有负数

string& insert(size_t pos, char c)
{if (_size + 1 > _capacity){reserve(_size + 1);char* tmp = new char[_capacity + 1];strcpy(tmp, _str);delete[]_str;_str = tmp;}size_t end = _size;while (end >= pos){_str[end + 1] = _str[end];;end--;}_str[pos] = c;_size++;_str[_size] = '\0';return *this;
}
string& insert(size_t pos, const char* str)
{size_t len = strlen(str);if (_size + len > _capacity){reserve(_size + len);char* tmp = new char[_capacity + 1];strcpy(tmp, _str);delete[]_str;_str = tmp;}size_t end = _size;while (end >= pos){_str[end + len] = _str[end];end--;}strncpy(_str + pos, str, len);_size += len;return *this;
}

5.erase

pos位置开始删除len个数据

string& erase(size_t pos, size_t len)
{if (len == npos && len + pos > _size){_str[pos] = '\0';}else{while (pos+len<_size){_str[pos] = _str[pos + len];pos++;}_size -= len;_str[_size] = '\0';}return *this;
}

6.流插入<<

ostream& operator<<(ostream& _cout, const bit::string& s)
{for (int i = 0; i < s._size; i++){_cout << s[i] << "";}_cout << endl;return _cout;
}

7.流提取>>

输入多个值,C++规定 空格/换行是值与值之间的区分

istream& operator>>(istream& _cin, bit::string& s)
{s.clear();char ch = _cin.get();char buf[128];int index = 0;while (ch != ' ' && ch != '\n'){buf[index++] = ch;if (index == 127){buf[index] = '\0';s += buf;index = 0;}ch = _cin.get();}if (index != 0){s += buf;}return _cin;
}

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

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

相关文章

C++类与对象(拷贝与类的内存管理)

感谢大佬的光临各位&#xff0c;希望和大家一起进步&#xff0c;望得到你的三连&#xff0c;互三支持&#xff0c;一起进步 个人主页&#xff1a;LaNzikinh-CSDN博客 文章目录 前言一.对象的动态建立和释放二.多个对象的构造和析构三.深拷贝与浅拷贝四.C类的内存管理总结 前言 …

element-plus日历组件el-calendar自定义内容,每天绑定不同的值

效果 代码 <template><el-calendar v-model"calendarDate"><template #date-cell"{ data }"><p :class"data.isSelected ? is-selected : ">{{ data.day.split("-").slice(1).join("-") }}{{ d…

LE Audio音频广播新功能Auracast介绍

LE Audio音频广播新功能Auracast介绍 /*! \copyright Copyright (c) 2019-2022 Qualcomm Technologies International, Ltd. All Rights Reserved. Qualcomm Technologies International, Ltd. Confidential and Proprietary. \file audio_sources.h \defgroup audio_so…

最新网赚骗局详细解析

最新网赚骗局多种多样&#xff0c;而且随着技术的发展&#xff0c;这些骗局也在不断演变和升级。以下是一些揭秘最新网赚骗局的要点&#xff1a; 1. 刷单返利类诈骗&#xff1a;骗子往往通过微信群、QQ群等社交平台发布虚假的刷单任务&#xff0c;承诺完成刷单任务后可以获得高…

IDEA创建SpringBoot项目的时候,如何使用Java8,怎么办?

在创建springboot项目的时候,IDEA提示&#xff0c;最低Java版本要求17&#xff0c;但是实际上我们可能不需要这么高的版本&#xff0c;怎么使用Java8呢&#xff1f; 解决办法 修改Server URL地址即可&#xff1a;https://start.aliyun.com

pika消费者退出

pika消费者退出问题 https://stackoverflow.com/questions/32220057/interrupt-thread-with-start-consuming-method-of-pika import threading import pikaclass WorkerThread(threading.Thread):def __init__(self):super(WorkerThread, self).__init__()self._is_interrupte…

天才程序员周弈帆 | Stable Diffusion 解读(二):论文精读

本文来源公众号“天才程序员周弈帆”&#xff0c;仅用于学术分享&#xff0c;侵权删&#xff0c;干货满满。 原文链接&#xff1a;Stable Diffusion 解读&#xff08;二&#xff09;&#xff1a;论文精读 【小小题外话】端午安康&#xff01; 在上一篇文章天才程序员周弈帆 …

【数据结构】排序(上)

个人主页~ 堆排序看这篇~ 还有这篇~ 排序 一、排序的概念及应用1、概念2、常见的排序算法 二、常见排序的实现1、直接插入排序&#xff08;1&#xff09;基本思想&#xff08;2&#xff09;代码实现&#xff08;3&#xff09;时间复杂度&#xff08;4&#xff09;空间复杂度 2…

【设计模式】创建型设计模式之 工厂模式

一、介绍 工厂模式可以分为 3 个小类 简单工厂模式工厂方法模式抽象工厂模式 工厂模式的工厂类&#xff0c;并不一定以 Factory 结尾&#xff0c;例如 DataFormat、Calender 他们都是工厂类&#xff0c;通过静态方法来创建实例。 除此之外&#xff0c;创建对象的方法名称一…

VBA即用型代码手册:删除重复行Delete Duplicate Rows

我给VBA下的定义&#xff1a;VBA是个人小型自动化处理的有效工具。可以大大提高自己的劳动效率&#xff0c;而且可以提高数据的准确性。我这里专注VBA,将我多年的经验汇集在VBA系列九套教程中。 作为我的学员要利用我的积木编程思想&#xff0c;积木编程最重要的是积木如何搭建…

电商项目-day01

文章目录 虚拟机的导入 虚拟机的导入 现根据镜像文件进行导入

streamlit:如何快速构建一个应用,不会前端也能写出好看的界面

通过本文你可以了解到&#xff1a; 如何安装streamlit&#xff0c;运行起来第一个demo熟悉streamlit的基本语法&#xff0c;常用的一些组件使用streamlit库构建应用 大模型学习参考&#xff1a; 大模型学习资料整理&#xff1a;如何从0到1学习大模型&#xff0c;搭建个人或企业…

(二)深度学习基础练习题(54道选择题)

本文整理了深度学习基础知识相关的练习题&#xff0c;共54道&#xff0c;适用于想巩固深度学习基础的同学。来源&#xff1a;如荷学数据科学题库&#xff08;技术专项-深度学习&#xff09;。 1&#xff09; 2&#xff09; 3&#xff09; 4&#xff09; 5&#xff09; 6&#…

音程与和弦 音程协和度

2个音符之间的音程计算 1234567&#xff0c;1到7的音程是7度&#xff0c;音程是计算总长度&#xff0c;看音级的个数。 Cubase中的音程计算 下面一个是4度&#xff0c;一个是3度&#xff0c;格子中深色的行就是黑键行。 根据半音数量来确定对应音程的专业术语叫法 旋律音程、…

用咖啡来理解springboot3的自动配置机制

大家好&#xff0c;这里是教授.F 目录 前提知识&#xff1a; 场景引入&#xff1a; 1.Starter依赖&#xff1a; 2.默认配置&#xff1a; 3.自定义配置&#xff1a; 4.条件化配置&#xff1a; 5.自动装配&#xff1a; 具体过程&#xff1a; 扫包路径的配置&#xff1a; 配置…

解锁ChatGPT:从GPT-2实践入手解密ChatGPT

⭐️我叫忆_恒心&#xff0c;一名喜欢书写博客的研究生&#x1f468;‍&#x1f393;。 如果觉得本文能帮到您&#xff0c;麻烦点个赞&#x1f44d;呗&#xff01; 近期会不断在专栏里进行更新讲解博客~~~ 有什么问题的小伙伴 欢迎留言提问欧&#xff0c;喜欢的小伙伴给个三连支…

【深度学习】—— 神经网络介绍

神经网络介绍 本系列主要是吴恩达深度学习系列视频的笔记&#xff0c;传送门&#xff1a;https://www.coursera.org/deeplearning-ai 目录 神经网络介绍神经网络的应用深度学习兴起的原因 神经网络&#xff0c;全称人工神经网络&#xff08;Artificial Neural Network&#xf…

python生成免费的ssl证书

测试SSL证书不需要验证域名权限 执行 pip install cryptography from cryptography import x509 from cryptography.x509.oid import NameOID from cryptography.hazmat.primitives import hashes, serialization from cryptography.hazmat.primitives.asymmetric import r…

私有化AI搜索引擎FreeAskInternet

什么是 FreeAskInternet FreeAskInternet 是一个完全免费、私有且本地运行的搜索聚合器&#xff0c;并使用 LLM 生成答案&#xff0c;无需 GPU。用户可以提出问题&#xff0c;系统将使用 searxng 进行多引擎搜索&#xff0c;并将搜索结果合并到ChatGPT3.5 LLM 中&#xff0c;并…

Python私教张大鹏 Vue3整合AntDesignVue之Breadcrumb 面包屑

显示当前页面在系统层级结构中的位置&#xff0c;并能向上返回。 何时使用 当系统拥有超过两级以上的层级结构时&#xff1b; 当需要告知用户『你在哪里』时&#xff1b; 当需要向上导航的功能时。 案例&#xff1a;面包屑导航基本使用 核心代码&#xff1a; <template…