跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像AI 生图工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C++算法

C++ 入门:string 类详解与模拟实现

C++ string 类是处理文本的核心工具,相比 C 语言字符数组更安全便捷。涵盖 string 常用接口、构造方式、容量管理、遍历方法及底层原理。重点解析浅拷贝与深拷贝的区别,写时拷贝(COW)机制及其在 fork、Redis 等场景的应用。通过模拟实现 string 类,深入理解资源管理与内存安全,适合准备面试或希望夯实基础的开发者。

落日余晖发布于 2026/3/29更新于 2026/7/1936 浏览
C++ 入门:string 类详解与模拟实现

C++ string 类详解

在 C++ 中,std::string 是处理文本的核心组件。相比 C 语言的字符数组,它提供了更安全的内存管理、丰富的接口以及自动扩容能力。本文将系统梳理 string 类的常用接口、底层原理及面试中的常见考点。

一、基础语法辅助

在使用 string 之前,了解两个 C++11 特性会让代码更简洁。

1. auto 关键字

auto 让编译器根据初始值推导变量类型。使用 auto 时变量必须初始化。

auto x = 10;       // 推导为 int
auto y = 3.14;     // 推导为 double
auto ptr = &x;     // 推导为 int*

注意:同一行声明多个变量时,它们必须是相同类型。例如 auto a = 10, b = 20; 正确,但 auto a = 10, b = 3.14; 会报错。

2. 范围 for 循环

基于范围的 for 循环简化了容器和数组的遍历。

int arr[] = {1, 2, 3};
for (int x : arr) {
    cout << x << " ";
}

string str = "hello";
for (char c : str) {
    cout << c << " ";
}

若需修改元素,建议使用引用:for (auto& e : arr)。

二、string 类常用接口

1. 构造方式

构造函数说明
string()构造空字符串
string(const char* s)用 C 风格字符串构造
string(size_t n, char c)构造包含 n 个字符 c 的字符串
string(const string& s)拷贝构造
string s1;                  // 空串
string s2("Hello");         // C-string 构造
string s3(5, '*');          // *****
string s4(s2);              // 拷贝构造

2. 容量操作

  • size() / length(): 返回有效字符长度,两者底层原理一致。
  • capacity(): 返回当前分配的总空间大小。
  • empty(): 判断是否为空。
  • clear(): 清空有效字符,但不释放底层空间(capacity 不变)。
  • resize(n, c): 调整有效字符个数,超出部分用 c 填充。
  • reserve(n): 预留空间,不改变有效字符数,仅当 n 大于当前 capacity 时扩容。
string s = "hello";
s.reserve(100);             // 预留空间,size 仍为 5
s.resize(10, 'x');          // helloxxxxx

3. 访问与遍历

  • operator[]: 下标访问,可读写。
  • begin() / end(): 获取迭代器,用于正向遍历。
  • rbegin() / rend(): 反向迭代器。
  • 范围 for: C++11 推荐方式。
string s = "Hello";
// 下标访问
s[0] = 'h';

// 迭代器遍历
for (auto it = s.begin(); it != s.end(); ++it) {
    cout << *it << " ";
}

// 范围 for
for (char c : s) {
    cout << c << " ";
}

4. 修改操作

  • push_back(c): 尾插单个字符。
  • append(str): 追加字符串。
  • operator+=: 最常用的追加方式。
  • c_str(): 返回 C 风格字符串指针,用于兼容旧接口。
  • find(): 查找子串位置,未找到返回 string::npos。
  • substr(pos, len): 截取子串。
string s = "Hello";
s.push_back('!');           // Hello!
s += " World";              // Hello! World
const char* cStr = s.c_str();
size_t pos = s.find("World");
string sub = s.substr(6, 5);

5. 非成员函数

  • operator+: 连接字符串,注意传值返回可能涉及深拷贝,性能略低。
  • operator>> / operator<<: 输入输出重载。
  • getline(cin, s): 读取整行字符串(含空格)。
  • 关系运算符:支持字典序比较。

三、string 结构差异

不同编译器下 string 内部结构略有不同,以 32 位平台为例:

  • VS 编译器: 通常占用 28 字节。短字符串(<16 字符)使用内部缓冲(SSO),长字符串才分配堆内存。
  • G++ 编译器: 早期版本常采用写时拷贝(COW)机制,对象本身较小,通过引用计数管理共享内存。

四、模拟实现与内存安全

面试中常要求手写 String 类,核心在于资源管理。

1. 浅拷贝与深拷贝

默认拷贝构造函数执行浅拷贝,即直接复制指针地址。这会导致析构时重复释放同一块内存,引发崩溃。

// 错误示例:浅拷贝
class String {
public:
    String(const char* str) {
        _str = new char[strlen(str) + 1];
        strcpy(_str, str);
    }
    ~String() { delete[] _str; }
private:
    char* _str;
};
// 测试
String s1("hello");
String s2(s1); // s2._str 指向与 s1 相同的地址

解决方案:手动实现深拷贝,为新对象分配独立内存。

String(const String& s) {
    _str = new char[strlen(s._str) + 1];
    strcpy(_str, s._str);
}

2. 赋值运算符重载

需处理自赋值情况,并释放原有资源。

String& operator=(const String& s) {
    if (this != &s) {
        delete[] _str;
        _str = new char[strlen(s._str) + 1];
        strcpy(_str, s._str);
    }
    return *this;
}

现代 C++ 推荐使用拷贝交换惯用法,利用移动语义或临时对象减少开销。

3. 写时拷贝(Copy-on-Write, COW)

COW 是一种优化策略,结合了浅拷贝的速度和深拷贝的安全性。

  • 读操作:共享内存,无额外开销。
  • 写操作:触发时复制数据,确保互不影响。

应用场景:

  • Linux fork() 系统调用:父子进程共享内存页,修改时才复制。
  • Redis bgsave:子进程持久化时共享父进程内存视图。
  • Java CopyOnWriteArrayList:读多写少场景下的线程安全 List。

五、总结

掌握 string 类不仅意味着会使用 API,更要理解其背后的内存管理机制。从浅拷贝陷阱到 COW 优化,这些知识点在面试和实际开发中都至关重要。建议结合源码阅读,深入体会标准库的设计思想。

目录

  1. C++ string 类详解
  2. 一、基础语法辅助
  3. 1. auto 关键字
  4. 2. 范围 for 循环
  5. 二、string 类常用接口
  6. 1. 构造方式
  7. 2. 容量操作
  8. 3. 访问与遍历
  9. 4. 修改操作
  10. 5. 非成员函数
  11. 三、string 结构差异
  12. 四、模拟实现与内存安全
  13. 1. 浅拷贝与深拷贝
  14. 2. 赋值运算符重载
  15. 3. 写时拷贝(Copy-on-Write, COW)
  16. 五、总结
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • AI 辅助开发:自动追踪 JXX 登录域名变更方案
  • 从表单到 JSON:Spring Boot 前后端交互三案例
  • 从零开始学习大模型:如何构建与部署开源大语言模型
  • Python 基础语法完全指南:变量、类型、运算符与字符串处理
  • 为什么 AI 大模型是智能座舱的最佳打开方式
  • C++ 数据结构:用链表实现队列
  • AI 技术动态:Claude 记忆插件、LangChain DeepAgents 与具身智能进展
  • 网络安全基础概念与加密技术详解
  • Web3 开发者入门:从零构建首个 DApp 实战指南
  • C++ 面试核心考点:内存管理、编译机制与类型系统
  • Spring AI 实现 RAG 检索增强生成详解与实践
  • 构建医学文献智能助手:基于 LangChain 的专业领域 RAG 系统实践
  • 5 款免费 AI 降重与去痕工具推荐
  • Python 结合 Neo4j 构建知识图谱入门实战
  • 无人机航拍人员搜救检测数据集(YOLO 标注格式)
  • 汽车雷达多径干扰下的幽灵目标检测与算法分析
  • Clawdbot 开源 AI 助手国内部署教程:镜像加速与环境配置
  • Linux 编译器 gcc/g++与动态静态库详解
  • JVM 高频面试题:CPU 飙高与 OOM 排查
  • 自然语言处理在金融领域的应用与实战

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online