当前位置: 首页 > news >正文

手撕string类

1.string类的成员变量 1指针指向申请的空间  2.size字符串长度 3.capacity字符串容量 

        注意 申请的空间=capacity容量+1  1是留给 \0 

2.STL中的string 字符串长度<=15 在栈上申请空间  >15才会在堆上申请空间。但我们统一在堆上申请空间。

3.要实现的函数

        1.构造函数: 1.默认构造 2.带参构造 (有两种 1.C风格字符串构造 带\0结尾 2.二进制字符串构造 不带\0传入size大小 划定界限)   3.拷贝构造 4.移动构造 5.析构函数

        2.赋值运算符重载 1.拷贝赋值运算符重载 2.移动赋值运算符重载

        3.预分配内存reserve  释放多余内存shrink_to_fit

        4.尾加字符串append函数(1.C风格 2.二进制)

        5.其它函数 1.c_str 2.size 3.capacity 4.empty判空

1.内存管理

申请一块大小为newcap+1大小的空间,把原数据拷贝过去,并把申请的原空间释放

        1.newcap<_size+1 说明新空间不能存放所有的原数据 抛异常

invalid_argument表示传入参数错误 runtime_error程序运行过程中遇到问题

        2.申请的字符串容量newcap最小为15

因为我们不知道要复制的原空间字符串是否以\0结尾,

所有用memcpy(目标空间起始地址,原空间起始地址,拷贝字节数)控制要拷贝的字节数,只拷贝size字符串长度大小的空间,最后自己手动加上\0

2.构造函数

1.默认构造

容量最小15

2.C风格字符串构造

1.带参构造函数加上 explicit禁止隐式类型转换

        

3.C风格以\0结尾  memcpy拷贝的时候可以把\0也拷贝进去

注意:sizeof(str):算的是指针的大小

sizeof(*str):*str表示字符串数组第一个字符 也就是大小为1 

strlen(str):算字符串的长度  但以\0为分界线,只能算以\0结尾的字符串

3.二进制风格字符串

1.explicit 禁止隐式转换

2.判空

3.拷贝完len大小的字符串后,手动加\0

4.拷贝构造

5.移动构造

1.移动语义(移动构造 移动赋值)+x析构函数 加noexcept,表示不会进行抛异常,这样容器在移动元素时会选择移动语义 减少拷贝 提高效率。

2.记得把原资源置为空

6.析构函数

 1. 析构函数默认是 noexcept(true),但手动写时最好明确

虽然编译器默认会将析构函数视为不抛异常,但你自己定义的析构函数如果不加 noexcept某些标准库操作会认为它可能抛异常,从而影响:

  • 标准容器如 std::vector<T> 是否能使用移动优化。

  • std::swap 等泛型算法是否使用移动而非拷贝。


2. 不加 noexcept 会影响标准库优化路径

例如在 std::vector<string> 中:

  • 如果 string 的析构函数不是 noexcept,移动操作可能回退为拷贝,降低性能。

  • 编译器会避免在 noexcept 不确定的情况下做 move 优化。


3. 析构函数本身不该抛异常

C++ 的一个基本原则是:析构函数绝不能抛出异常,否则程序会在异常传播时“再次抛出”导致 std::terminate() 被调用。

因此,加上 noexcept 是对这个约定的明确表达,也是一种安全保障

3.赋值运算符重载

1.拷贝运算符重载

1.先判断是否是自身,是就直接返回*this

2.把申请的原空间进行释放

3.申请新空间进行拷贝操作

2.移动赋值运算符

1.赋值运算符 先判断自身

2.移动 加noexcept

3.释放原空间 但不用申请新空间直接指向other的空间 让other指向空

4.扩容 缩容操作

5.append函数

1.二进制风格

在原字符串后面加上长度为len为字符串

1.先判空 

2.先判断capacity空间是否还够  不够就进行扩容  *2+len +len防止扩容后仍不够

3.在原字符串结尾处即\0处进行memcpy拷贝

4.最后加上\0结尾

2.C风格

进行复用

6.其它函数 

... c_str() const

  • 表示该函数是一个常量成员函数

  • 它不修改当前对象的成员变量(除非是 mutable 变量)。

  • 这意味着你可以在 const string 对象上调用它:

位置作用示例
const char*返回值指向的是 const 数据(不能改)const char* p = str.c_str();
... const修饰成员函数,表示不修改对象const string s; s.data();

http://www.xdnf.cn/news/640567.html

相关文章:

  • 汉诺塔超级计算机堆栈区与数据区的协同
  • Docker(零):本文为 “Docker系列” 有关博文的简介和目录
  • Docker核心笔记
  • JavaWeb:SpringBoot配置优先级详解
  • 互联网大厂Java求职面试:AI应用集成中的RAG系统优化与向量数据库性能调优实战
  • 英语科研词汇的困境与汉语的崛起之光
  • 漫谈英伟达GPU架构进化史:从Celsius到Blackwell
  • vue3中使用watch
  • 什么是智能体agent?
  • Anaconda 常用命令汇总
  • Mongo DB | 多种修改数据库名称的方式
  • 明阳智慧能源社招校招入职测评 |iLogic言语逻辑数字、Talent5大五职业性格测评、TAS倍智人才测评考什么
  • 资源-又在网上淘到金了-三维模型下载
  • CodeTop之LRU缓存
  • SQL JOIN
  • 4款顶级磁力下载工具,速度提升器,可以变下变播
  • 【RocketMQ 生产者和消费者】- 生产者发送故障延时策略
  • MATLAB在逐渐被Python淘汰吗
  • 【Java高阶面经:缓存篇】35、 Redis单线程 vs Memcached多线程:高性能内存数据库设计解析
  • ComfyUI进行海报创作
  • 【Linux 学习计划】-- 冯诺依曼体系 | 操作系统的概念与定位,以及其如何管理软件
  • Reactor模式详解:高并发场景下的事件驱动架构
  • ROI智能计算精灵
  • Google 推出 Flow —— AI 电影制作新平台
  • 浏览器游戏的次世代革命:WebAssembly 3.0 实战指南
  • 微雪2.7英寸墨水屏 API函数 解释
  • 大模型BERT登顶刊CAR!分析专利文本的作用
  • 开源项目跨平台桌宠 BongoCat,为桌面增添乐趣!
  • SEO搜索引擎优化
  • log日志最佳实践