前言
本书是一份面向生产环境的现代 C++23 实践指南,不是语言教程,也不是现代化改造手记。目标读者是这样的程序员:熟悉软件的构建、测试、发布和调试流程,但需要一套可靠的方法论,在真实的设计压力下做出合理的 C++ 决策。本书关注的不是语法罗列,而是所有权、生命周期、接口设计、错误边界、并发、数据布局、性能度量与验证。
本书假定你不需要别人教你写循环或配置编辑器。你真正需要的帮助在于:一个函数应该用 std::string_view 还是 std::span<const std::byte> 来借用数据?所有权应该在哪里转移?遇到错误时应该抛异常还是返回 std::expected?什么时候用 range 管道能让算法意图更清晰?什么时候协程帧会变成生命周期隐患?什么证据才足以证明性能确实提升了?如果你想要的是特性巡览、入门教程或按头文件编排的参考手册,那这本书不适合你。
这一前提是有意为之。你不必是 C++ 专家,但你得是一名有经验的工程师——能读懂有一定复杂度的代码,能推敲 API 的行为,能跨子系统追踪控制流,并且日常打交道的就是测试、调试、性能优化和工程取舍。本书正是为这样的读者而写。
全书共分七个部分。第一、二部分建立心智模型和日常概念体系,为写出可审查的代码打下基础。第三部分向外延伸,涵盖接口、多态、库、模块以及 ABI 的现实约束。第四、五部分讨论并发、数据布局、内存分配与性能测量。第六部分关注验证与诊断工具链,确保原生系统的行为可追溯、可验证。第七部分以完整的生产实例收尾:一个服务、一个可复用库,以及一套代码评审工作流。
之所以采用这样的结构,是因为 C++ 中代价高昂的故障很少是局部性的。一个服务用 shared_ptr 延续请求状态的生命,把工作扇出到后台任务,靠副作用记录错误,结果在关停时卡死。一个库在边界处接受借用的 view,却把它留存到调用方的生命周期之外。一次性能重构消除了一次拷贝,却在别处悄悄引入了锁争用和分配器压力。单独看,每个局部决策都可能是合理的;但当所有权、时序、错误传播和成本模型交织在一起时,问题就会暴露出来。
未定义行为(UB)是另一条贯穿全书的压力线,而不是关在某一章里一次性讲完。悬空引用、数据竞争、失效的迭代器,或是一条悄悄活过了数据源的 view 管道——这些都可能让一个看似合理的设计仅在开启优化、承受高负载或切换工具链时才暴露问题。所有权、并发、性能和工具链相关章节各自讨论了与本领域最密切相关的 UB 风险。请把对 UB 的警觉当作串联全书的主线,而不是某处一贴即忘的警告标签。
如何阅读本书
你可以从头到尾顺序阅读。各部分的编排旨在逐层构建判断力:先讲所有权与不变量,再讲日常库和语言工具,然后是架构、并发、性能、验证,最后是完整的生产模式。不过,如果你已经明确要解决的问题类别,也完全可以直接跳到对应章节:
| 起点 | 推荐章节 |
|---|---|
| 设计接口或库边界 | 第 4、9、10、11 和 22 章 |
| 构建或修复原生服务 | 第 1、3、12、13、14、20 和 21 章 |
| 编写泛型且可复用的实现代码 | 第 5、6、7、8 和 22 章 |
| 处理热路径、内存行为或测量 | 第 15、16 和 17 章 |
| 强化验证与构建诊断 | 第 18、19 和 20 章 |
| 评审生产级 C++ 变更 | 第 1、3、4、14、19、22 和 23 章 |
每章开头都会列出前置知识要求,所以你可以直接从问题所在处切入,只在需要时回头补充背景。附录提供了精炼的辅助材料:面向决策的特性索引、工具链与诊断配置基线、简明的代码评审检查清单,以及本书核心术语的规范词汇表。
本书以 C++23 为主要基线。只有当 C++26 会改变你当下的决策,或能显著降低现有模式的开销时,才会提及它。引入这些前瞻性内容,是为了让建议经得起近期发展的检验,而非把本书变成标准演进的评论文章。
如果本书达到了预期效果,你应该能审视一个设计或一份 diff,讲清其中的权衡:它换来了什么,冒了什么风险,给调用方或运维带来了哪些承诺,以及需要什么证据才能证明这个选择站得住脚。这就是”知道现代 C++ 有哪些特性”与”真正用好现代 C++”之间的差距。