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

手写C++ string类实现详解

类定义

cpp

namespace ym {class string {private:char* _str;        // 字符串数据size_t _size;      // 当前字符串长度size_t _capacity;  // 当前分配的内存容量static const size_t npos = -1;  // 特殊值,表示最大可能位置public:// 构造函数和析构函数string(const char* str = "");string(const string& s);~string();// 迭代器支持typedef char* iterator;typedef const char* const_iterator;iterator begin();iterator end();// ... 其他成员函数};
}

核心功能实现

1. 内存管理

reserve() 函数

cpp

void string::reserve(size_t n) {if (n > _capacity) {char* str = new char[n + 1];  // 多分配1字节存放'\0'strcpy(str, _str);delete[] _str;_str = str;_capacity = n;}
}
push_back() 函数

cpp

void string::push_back(char ch) {if (_size == _capacity) {reserve(_capacity == 0 ? 4 : 2 * _capacity);  // 初始容量为4,之后每次翻倍}_str[_size++] = ch;_str[_size] = '\0';  // 确保字符串始终以'\0'结尾
}

2. 字符串操作

append() 函数

cpp

void string::append(const char* str) {size_t len = strlen(str);if (_size + len > _capacity) {reserve(max(_size + len, 2 * _capacity));  // 按需扩容}strcat(_str + _size, str);  // 追加字符串_size += len;
}
insert() 函数

cpp

void string::insert(size_t pos, const char* str) {assert(pos <= _size);size_t len = strlen(str);if (_size + len > _capacity) {reserve(_size + len);}// 向后移动字符memmove(_str + pos + len, _str + pos, _size - pos + 1);  // +1包含'\0'// 插入新内容memcpy(_str + pos, str, len);_size += len;
}

3. 运算符重载

赋值运算符

cpp

string& string::operator=(string s) {if (this != &s) {  // 防止自赋值delete[] _str;_str = new char[s._capacity + 1];strcpy(_str, s._str);_size = s._size;_capacity = s._capacity;}return *this;
}
比较运算符

cpp

bool operator<(const string& s1, const string& s2) {return strcmp(s1.c_str(), s2.c_str()) < 0;
}
// 其他比较运算符类似...

4. 流操作符

输出运算符

cpp

ostream& operator<<(ostream& out, const string& s) {for (auto ch : s) {  // 使用范围for循环out << ch;}return out;
}
输入运算符(优化版)

cpp

istream& operator>>(istream& in, string& s) {s.clear();const int N = 256;  // 缓冲区大小char buff[N];int i = 0;char ch;// 跳过前导空白while (in.get(ch) && isspace(ch)) {}// 读取直到遇到空白if (!in.eof()) {do {buff[i++] = ch;if (i == N - 1) {  // 缓冲区快满时buff[i] = '\0';s += buff;i = 0;}} while (in.get(ch) && !isspace(ch));// 处理剩余字符if (i > 0) {buff[i] = '\0';s += buff;}}return in;
}

关键设计点

  1. 内存管理

    • 使用new[]delete[]手动管理内存

    • 采用指数级扩容策略(初始4,之后每次翻倍)

    • 始终确保字符串以'\0'结尾

  2. 异常安全

    • 赋值运算符使用拷贝交换惯用法

    • 关键操作前进行断言检查

  3. 性能优化

    • 输入操作符使用缓冲区减少扩容次数

    • 使用memmovememcpy提高大块数据操作效率

  4. 标准兼容

    • 提供迭代器支持

    • 实现完整的比较运算符

    • 支持流操作符

使用示例

cpp

ym::string s1 = "Hello";
ym::string s2 = "World";s1 += " ";
s1 += s2;  // s1变为"Hello World"cout << s1 << endl;  // 输出: Hello Worldym::string s3;
cin >> s3;  // 读取输入
http://www.lryc.cn/news/626074.html

相关文章:

  • 使用redis读写锁实现抢券功能
  • 怎样平衡NLP技术发展中数据质量和隐私保护的关系?
  • JVM 面试精选 20 题(续)
  • JVM对象创建和内存分配
  • SpringAI接入openAI配置出现的问题全解析
  • 今日行情明日机会——20250819
  • Java开发面试实战:Spring Boot微服务与数据库优化案例分析
  • 星图云开发者平台新功能速递 | 微服务管理器:无缝整合异构服务,释放云原生开发潜能
  • 微服务如何集成swagger3
  • 微服务-08.微服务拆分-拆分商品服务
  • UE5 使用RVT制作地形材质融合
  • idea如何设置tab为4个空格
  • CSS backdrop-filter:给元素背景添加模糊与色调的高级滤镜
  • Day08 Go语言学习
  • Ansible 中的文件包含与导入机制
  • 常见 GC 收集器与适用场景:从吞吐量到亚毫秒停顿的全景指南
  • NestJS 依赖注入方式全解
  • TDengine IDMP 运维指南(3. 使用 Ansible 部署)
  • 【上升跟庄买入】副图/选股指标,动态黄色线由下向上穿越绿色基准线时,发出买入信号
  • day32-进程与线程(5)
  • Ubuntu 下面安装搜狗输入法debug记录
  • Ubuntu一键安装harbor脚本
  • WSL虚拟机(我的是ubuntu20.04)将系统文件转移到E盘
  • 机器学习之决策树:从原理到实战(附泰坦尼克号预测任务)
  • LINUX819 shell:for for,shift ,{} ,array[0] array[s] ,declare -x -a
  • 中科米堆CASAIM提供机加工件来料自动化测量尺寸方案
  • 中国互联网医院行业分析
  • Linux下Mysql命令,创建mysql,删除mysql
  • 基于多级缓存架构的Redis集群与Caffeine本地缓存实战经验分享
  • 原牛:一站式自媒体工具平台