《告别 “会用不会讲”:C++ string 底层原理拆解 + 手撕实现,面试 / 开发都适用》
0基础手撕从0搭建string核心底层逻辑(附实现代码)2.1 底层构造逻辑string类的成变量与构造逻辑string 的底层本质上是靠三个成员变量支撑先搭建好基本类框架再逐步实现功能新手也能一步步自己手撕出一个基本的string类。string.h代码语言javascriptAI代码解释#pragma once #includeiostream #includeassert.h #includealgorithm #includestring.h using namespace std; namespace Lotso { class string { public: string(const char* str ); string(const string s); //先实现这个是为了在还没实现cout前方便测试打印观察 const char* c_str()const { return _str; } string operator(const string s); ~string(); void resize(size_t n, char c \0); void reserve(size_t n); size_t size()const { return _size; } size_t capacity()const { return _capacity; } private: char* _str; size_t _capacity; size_t _size; public: //这里比较特殊const static整型可以这么用特殊处理 //当然也可以声明和定义分离 const static size_t npos -1; //const static double npos-1;//这个是不行的 }; };2.1.1 构造与析构对象的 “创建” 与 “销毁”构造函数负责为 string 对象分配初始内存初始化状态析构函数则在对象生命周期结束时回收动态分配的内存避免泄漏。同时拷贝构造和赋值重载要实现深拷贝确保多个对象间内存的独立这个在之前类和对象中讲过这里也会把链接放上大家如果不理解这里深浅拷贝区别的一定要去看看当然在后续的创作中博主也会再详细解析一下这个问题的。参考往期博客《吃透 C 类和对象中拷贝构造函数与赋值运算符重载深度解析》-CSDN博客代码演示(注意看注释)string.h代码语言javascriptAI代码解释public: string(const char* str ); string(const string s); string operator(const string s); ~string();string.cpp代码语言javascriptAI代码解释//构造 string::string(const char* str)//.h里面给缺省值 :_size(strlen(str)) { //_size strlen(str);//这个写里面也可以 //初始化列表初始化顺序跟声明顺序有关 //所以这里写在函数体里比较好可以灵活使用size _str new char[_size 1];//多开一个给\0; _capacity _size; strcpy(_str, str); } //析构 string::~string() { delete[] _str; _str nullptr; _size 0; _capacity 0; } //拷贝构造深拷贝避免内存共享 //string s2(s1); string::string(const string s) { _str new char[s._capacity 1]; //strcpy(_str, s._str);//这里可以用strcpy但是memcpy更好 memcpy(_str, s._str, s._size 1); _size s._size; _capacity s._capacity; } //赋值运算符重载先释放旧内存再深拷贝新内容 //s1s3 string string::operator (const string s) { if (this ! s) { char* tmp new char[s._capacity 1]; //strcpy(_str,s._str); //这里用memcpy是因为处理串里中间有\0的情况 memcpy(tmp, s._str, s._size 1); delete[] _str; _str tmp; _size s._size; _capacitys._capacity; } return *this; }--这里需要注意拷贝构造和赋值运算符重载都采用了深拷贝的方式即新对象会分配独立的内存空间来存储字符串内容而不是简单的直接复制指针这样可以避免多个对象共享同一块内存导致的重复释放等问题。2.1.2 c_str与辅助接口兼容C风格c_str 函数的作用是返回string对象内部存储的C风格字符串(以\0结束),方便与C语言的字符串处理进行交互。string.h代码语言javascriptAI代码解释public: // 返回C风格字符串方便兼容C语言接口 const char* c_str() const { return _str; } // 获取有效字符数 size_t size() const { return _size; } // 获取容量 size_t capacity() const { return _capacity; }2.1.3 容量管理resize和reserve的协同使用reserve 用于提前预留内存空间避免频繁扩容resize 则用于调整字符串的有效长度在需要时还会调用 reserve 进行扩容还可以指定填充字符。string.h代码语言javascriptAI代码解释public: void resize(size_t n, char c \0); void reserve(size_t n);string.cpp代码语言javascriptAI代码解释// 预留内存空间只改变容量不改变有效字符数 void string::reserve(size_t n) { if (n _capacity) { char* tmp new char[n 1]; //strcpy(tmp, _str); memcpy(tmp, _str, _size 1); delete[] _str; _str tmp; _capacity n; } } // 调整有效字符长度可指定填充字符 void string::resize(size_t n, char ch) { if (n _size) { //删除保留前n个 _size n; _str[_size] \0; } else { reserve(n); for (size_t i _size; i n; i) { _str[i] ch; } _size n; _str[_size] \0; } }--当 resize 的目标长度 n 超过当前容量时会调用 reserve 来扩容可以指定字符(默认为’\0‘)填充新的位置最后更新有效字符个数 _size 并在末尾补上\02.1.4 代码测试验证当前模块功能test.cpp代码语言javascriptAI代码解释namespace Lotso { void test_string1() { string s1; cout s1.c_str() endl; string s2(Hello Lotso); cout s2.c_str() endl; s2[0] h; for (size_t i 0; i s2.size(); i) { s2[i]; } cout s2.c_str() endl; string s3 hello world;//隐式类型转换构造拷贝构造-优化为构造 string s4(hello world); string s5; s5.resize(100, *); cout s5.c_str() endl; s5.resize(10); cout s5.c_str() endl; s5.resize(20, #); cout s5.c_str() endl; } }; int main() { try { Lotso::test_string1(); /* cout typeid(Lotso::string::iterator).name() endl; cout typeid(std::string::iterator).name() endl;*/ } catch (const exception e) { cout e.what() endl; } return 0; }补充测试这个运行结果没放出来--测试结果符合预期退出码为0该模块功能可以正常使用。2.2 迭代器与下标string遍历的两大高效工具2.2.1 迭代器的基本框架与实现迭代器是遍历容器元素的抽象机制对于string,可以通过封装指针来实现简单迭代器结合下标访问可以覆盖不同遍历场景。string.h代码语言javascriptAI代码解释typedef char* iterator; typedef const char* const_iterator; // iterator iterator begin() { return _str; } const_iterator begin() const { return _str; } iterator end() { return _str _size; } const_iterator end() const { return _str _size; }--这里将迭代器 typedef 为 char*begin 函数返回指向字符串起始位置的指针end 函数返回指向字符串有效字符结尾的下一个位置(\0所在的位置)的指针这样就可以利用指针的算术运算和解引用操作来实现迭代器的功能。2.2.2 operator[] 的底层逻辑与实现下标访问是string最常用的操作之一通过重载operator 可以像访问数组一样操作string的字符底层本质是对 _str 指针的索引访问同时也需要确保访问不会越界(这个可以加断言)string.h代码语言javascriptAI代码解释public char operator[](size_t index) { assert(index _size); return _str[index]; } const char operator[](size_t index)const { assert(index _size); return _str[index]; }operator 支持两种核心场景读取字符和修改字符配合循环可实现字符串遍历比迭代器更直观关键说明两个版本的重载非const版本返回char支持修改字符如s1iconst版本返回const char仅允许读取用于const对象。越界检查通过assert(pos_size)在调试阶段拦截越界访问 Release 模式下断言会失效若需严格检查可改为抛异常。与迭代器的对比operator 更适合已知索引的场景如随机访问第i个字符迭代器更适合范围遍历两者底层都是通过指针访问内存效率一致。2.2.3 代码测试验证当前模块功能test.cpp代码语言javascriptAI代码解释namespace Lotso { void test_string2() { string s2(Hello Lotso); cout s2.c_str() endl; s2[0] h; for (size_t i 0; i s2.size(); i) { s2[i]; } cout s2.c_str() endl; string s4(hello world); const string s5(hello Lotso); for (size_t i 0; i s5.size(); i) { //s5[i];不可以写但可以读 cout s5[i] -; } cout endl; for (auto ch : s4) { cout ch ; } cout endl; string::iterator it4 s4.begin(); while (it4 ! s4.end()) { *it4 1; cout *it4 ; it4; } cout endl; for (auto ch : s5) { cout ch ; } cout endl; string::const_iterator it5 s5.begin(); while (it5 ! s5.end()) { //*it51;//这个不行 cout *it5 ; it5; } cout endl; } }; int main() { try { //Lotso::test_string1(); Lotso::test_string2(); /* cout typeid(Lotso::string::iterator).name() endl; cout typeid(std::string::iterator).name() endl;*/ } catch (const exception e) { cout e.what() endl; } return 0; }--测试结果符合预期退出码为0该模块功能可以正常使用。2.3 字符串修改push_backappendinsert与的实现字符串的修改操作是string的核心功能push_back用于尾插单个字符append用于追加字符串insert支持指定位置插入但是三者的底层实现都需要处理内存扩容和确保高效的操作.

相关新闻

NI VeriStand与LabVIEW深度整合:自定义FPGA功能的全流程指南

NI VeriStand与LabVIEW深度整合:自定义FPGA功能的全流程指南

NI VeriStand与LabVIEW深度整合:自定义FPGA功能的全流程指南 在实时测试与硬件在环(HIL)仿真领域,工程师们常常面临一个核心矛盾:一方面需要标准化的、开箱即用的测试框架来保证开发效率和系统稳定性;另一方…

2026/7/5 3:59:04 阅读更多 →
JavaQuestPlayer:探索交互式叙事创作的价值与实践

JavaQuestPlayer:探索交互式叙事创作的价值与实践

JavaQuestPlayer:探索交互式叙事创作的价值与实践 【免费下载链接】JavaQuestPlayer 项目地址: https://gitcode.com/gh_mirrors/ja/JavaQuestPlayer 在数字内容创作领域,如何平衡技术实现与创意表达一直是创作者面临的核心挑战。JavaQuestPlaye…

2026/7/3 18:50:42 阅读更多 →
TimeGen 3.2时序图绘制技巧:从tg_draw到tg_scroll的完整操作指南

TimeGen 3.2时序图绘制技巧:从tg_draw到tg_scroll的完整操作指南

TimeGen 3.2时序图绘制技巧:从tg_draw到tg_scroll的完整操作指南 如果你已经安装了TimeGen 3.2,但每次画时序图时,总觉得操作不够流畅,效率提不上来,那你来对地方了。这篇文章不是一份简单的功能罗列,而是一…

2026/7/3 10:00:37 阅读更多 →

最新新闻

区分于三层架构的四层架构(Java 后端分层设计的完整指南)

区分于三层架构的四层架构(Java 后端分层设计的完整指南)

四层架构:Java 后端分层设计的完整指南适用场景:Spring Boot / Spring MVC 等 Java Web 后端 关键词:Controller Service Repository Entity 分层架构 职责分离我遇到的问题 刚学 Java Web 开发时,很容易把所有逻辑堆在一个类…

2026/7/5 3:57:09 阅读更多 →
Alexa增强与自主交通流耦合的语音交互新范式

Alexa增强与自主交通流耦合的语音交互新范式

1. 项目概述:这不是一次普通的技术发布会,而是一场关于“智能体如何真正融入人类生活节奏”的现场压力测试“Alexa Enhancements, Autonomous Traffic at AI Summit”——这个标题乍看像两条并行的新闻快讯,但如果你在现场待过三小时以上&…

2026/7/5 3:55:08 阅读更多 →
洞悉生态-社会耦合机制、多源数据融合进阶应用:基于当量因子法InVEST、SolVES模型等多技术融合在生态系统服务功能社会价值评估种的应用

洞悉生态-社会耦合机制、多源数据融合进阶应用:基于当量因子法InVEST、SolVES模型等多技术融合在生态系统服务功能社会价值评估种的应用

在生态文明建设的浪潮中,你是否正为如何量化那些难以用货币衡量的“人心账”而头疼?传统的生态评估往往只算清了“经济账”,却忽略了公众对美学、休闲和精神寄托的感知。作为破解这一难题的核心利器,当量因子法、InVEST与SolVES的…

2026/7/5 3:55:08 阅读更多 →
面试时,你会问面试官哪些问题?

面试时,你会问面试官哪些问题?

明天又要去参加一次面试。每次面试的时候,面试官都会在最后给面试者一些时间,来问问题。这是个非常好的机会,能按照自己的思路,来了解职位、技术、企业文化、福利待遇、企业状况和前景等情况,以弥补前面面试过程中没有…

2026/7/5 3:53:08 阅读更多 →
零基础!IntelliJ IDEA + CC GUI + 智谱AI 配置全记录

零基础!IntelliJ IDEA + CC GUI + 智谱AI 配置全记录

一、背景与目标 目标:在 IntelliJ IDEA 中使用 Claude Code 风格的 AI 编程助手,且希望免费、稳定、合规。 最终方案:IntelliJ IDEA CC GUI 插件 cc-switch 工具 智谱AI GLM 免费模型。 二、完整过程与遇到的问题 阶段 1:想…

2026/7/5 3:51:07 阅读更多 →
2026内蒙古制造业工厂线上获客方案,GEO+短视频+关键词排名组合打法

2026内蒙古制造业工厂线上获客方案,GEO+短视频+关键词排名组合打法

前言:制造业获客方式升级,线上渠道成必选项2026年,内蒙古的制造业工厂面临着新的挑战和机遇。传统的线下展会、客户转介绍等获客方式,效果越来越有限;而线上渠道正在成为制造业获客的新主战场。很多制造业工厂的老板已…

2026/7/5 3:51:07 阅读更多 →

日新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/5 0:03:34 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/5 0:03:34 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/5 0:07:38 阅读更多 →

周新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/5 0:03:34 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/5 0:03:34 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/5 0:07:38 阅读更多 →

月新闻