C++20代码整洁之道:可持续软件开发模式实践(原书第2版)
定 价:129 元
丛书名:程序员书库
本书全面更新至C 20,介绍如何使用现代C 编写可维护、可扩展和可持久的软件。对于每一个对编写整洁的C 代码感兴趣的开发人员、软件架构师或团队领导来说,这本书都是必需的。如果你想自学编写整洁的C 代码,本书也正是你需要的。本书旨在帮助所有级别的C 开发人员编写可理解的、灵活的、可维护的和高效的C 代码。即使是经验丰富的C 开发人员,也将受益匪浅。
首先,欢迎入坑!自己选择的路,跪着也要走到尽头。C 是王者的语言,是强者的工具,如果没有披荆斩棘的勇气,建议你尽快学习其他简单的语言。最近几年,陆陆续续出现了一些新的计算机编程语言,有些语言甚至在诞生之初就被程序员们打上了替代C 语言的标签。同时,有些程序员也会过度关注语言热度排行榜,认为学习C 语言已经没有前途了,真的是这样吗?我们不妨从几个方面来简单地分析一下。C或者C 是基础性的语言,也是更接近操作系统和核心组件库的语言。除操作系统外,目前所使用的大多数核心组件都是基于C或C 来实现的。C或者C 可以直接操作计算机的硬件资源,对于不熟悉计算机系统的人而言,这的确有一定的难度。换言之,使用这种语言需要具有一定的基础。C或者C 的确很高效,除了没有中间层之外,随着几十年的发展,编译器也越来越智能了。学习和掌握C 真的很难,但一旦掌握了,就会触类旁通,会获得非常多的收益。现在流行的一些语言,如Rust、Go、Python甚至Carbon语言,都是针对特定的目的和需求而设计的,这些语言诞生的初衷并不是取代C或者C 。那么,C或者C 就是目前最好的语言了吗?我认为并不是,时势造英雄,可以说C和C 语言是与计算机系统一起成长起来的,伟大的先驱们基于C或者C 构建了操作系统、计算机语言体系、数据库系统、网络软件等。当然,江山代有才人出,各领风骚数百年!计算机世界仍在快速发展,或许在未来的某一天,会出现一门集百家之长且足够优秀的语言,这种语言之父或许会诞生在你我之间。努力吧,少年!未来是你们的。时至今日,可以说C 是最复杂的语言,也是性能最好的语言之一。随着编译器越来越智能化,C 的性能在一些方面已经超越了其他语言。虽然C 的语法比较复杂,但C 也是既能够做底层开发,又能够兼容中、上层开发的语言。每种语言都有自己独有的特点,存在即合理,合适的就是最好的,所以我们应该辩证地分析问题,没有必要打口水仗。有人说PHP是世界上最好的语言,那又何妨?我曾经问过PHP之父(Rasmus Lerdorf)怎么看这个问题,他说这不是他所关心的。虽然C 曾经停滞过,但随着时间的推移和C 标准委员会的努力,C 98和C 03标准已经成为过去,C 1X和C 20已经推出并得到了主流编译器的支持,且C 23很快也会推出。伴随着许多新特性的加入,可以说C 11是一门全新的语言了,以前很多的观点或技巧已经不再适用于这门新时代的语言了。因此,如果想成为一名紧跟时代的程序员,你需要披荆斩棘,不断学习,用知识来武装自己。接下来,我们来简单介绍一下本书的内容。本书没有过多地提及C 的基础语法,也没有涉及高深莫测的技巧。书中涵盖了单元测试、整洁代码的基本原则、现代C 编程的高级概念、模块化编程、函数式编程、测试驱动开发及经典的设计模式等,与第1版相比,增加了C 20标准的诸多特性讲解。本书不太适合初学者(注意,C 和C有着本质的区别,是两种完全不同的语言。即使是C语言高手,如果以前没有C 开发经验,也只能算是C 初学者。可能很多人并不认同这个观点,那说明他们对C 还没有足够的了解),建议初学者先从《C Primer》学起,循序渐进。与很多其他语言(如Java、C#、Python等语言)相比,C 的学习之路是艰难的,因为学习C 不仅需要学习语言本身,而且在学习过程中会涉及许多其他方面的知识。如果没有这些方面的知识基础,C 学习起来就更困难了。如果能熟练掌握计算机基础理论,那么C 学起来就会相对容易一些;如果能读懂汇编代码,那么在探究C 编译器底层实现的时候也会有很大的帮助;如果没有良好的设计思想,那么很容易写出C风格的C 代码。因此,在掌握C 基本语法后,还需要逐步训练自己的面向对象思维,只因面向对象是基础,设计模式是提高,二者缺一不可。只有这些就够了吗?当然不是,还需要学习更多的东西才能学以致用!例如,还需要学习STL库、并发编程、网络IO模型、调试工具、第三方库等,但是不建议学习与界面有关的库,因为这是C 的短板。由此可见,学习C 涉及方方面面的知识,学习过程的艰难与困惑可想而知。但学习C 有一个极大的好处,那就是一旦能够驾驭C 了,再去学习其他语言时,就会轻车熟路你将会发现其他语言与C 相比只是语法不同而已,也更容易深入了解其他语言的底层实现,最终达到语言无界、触类旁通的境界。阅读此书前,建议你具备以下基础:了解单元测试的概念,最好有使用某单元测试框架编写单元测试的经验,这样你会有更深刻的体会。了解C 11、C 14、C 17的新特性,如智能指针、move语义、Lambda等。具有面向对象开发的基础,最好知道一些基本的原则,如SOLID原则等。了解测试驱动开发的基本思想。至少听说过设计模式。能看懂UML类图。最重要的一点:不满足于现状,渴望学习新东西,迫切想改变现在的自己。依然记得翻译第1版时的场景,但这版的翻译是一次全新的翻译,我们没有在第1版的基础上修改。在翻译这一版时,我们在术语的表达上做了较多的讨论和推敲,针对一些有争议的术语、内容,我们查阅了大量的资料。但即便如此,仍然难免存在疏忽、遗漏的地方。受限于译者的水平,书中也可能存在一些不准确的地方,如果你在阅读过程中刚好发现了翻译中的问题,你可以向出版社反馈。我们的初衷是帮助想学好C 的同人,希望本书能够促进你的学习,而不是对你造成误导。在此,我非常感谢和我一起翻译的几位同人,除了署名的译者,还有参与第1版翻译的骆名樊的女友,参与文前和封底翻译、进行部分校对以及充当顾问的赵守琦博士,在此,再次感谢大家!是你们的无私贡献让翻译进行得如此顺利,是你们的努力付出让翻译进度一直处在可控范围。由于篇幅原因,我无法在这里给出C 每个学习阶段应该阅读的主要书籍。我现在担任CSDN C/C 大版的版主和C 小版的版主,你可以在CSDN网站和我私下交流。谢谢机械工业出版社选择了这本书并给予我们无比的信任和翻译的机会!希望本书的内容及译文没有让读者失望。连少华
第1章 引言11.1 软件熵21.2 为什么使用C 31.3 整洁的代码41.4 C 11新时代的开始51.5 本书适合的读者61.6 本书使用的约定61.6.1 扩展内容71.6.2 注意事项、提示和警告71.6.3 示例代码71.7 相关网站和代码库81.8 UML图9第2章 构建安全体系102.1 测试的必要性102.2 测试入门122.3 单元测试142.4 关于质量保证162.5 良好单元测试的原则162.5.1 单元测试代码的质量162.5.2 单元测试的命名172.5.3 单元测试的独立性182.5.4 一个测试一个断言192.5.5 单元测试环境的独立初始化202.5.6 不对Getter和Setter做单元测试202.5.7 不对第三方代码做单元测试212.5.8 不对外部系统做单元测试212.5.9 如何处理数据库的访问212.5.10 不要混淆测试代码和产品代码222.5.11 测试必须快速执行242.5.12 如何设计测试的输入数据252.5.13 测试替身27第3章 原则313.1 什么是原则313.2 保持简单和直接原则323.3 不需要原则333.4 避免复制原则333.4.1 关于避免复制原则的知识343.4.2 构建抽象有时很困难343.5 信息隐藏原则373.6 高内聚原则403.7 松耦合原则423.8 小心优化原则453.9 最少惊讶原则463.10 童子军原则46第4章 C 代码整洁的基本规范484.1 良好的命名494.1.1 名称应该不言自明504.1.2 使用领域中的名称524.1.3 选择适当抽象级别的名称534.1.4 避免冗余的名称544.1.5 避免晦涩难懂的缩写544.1.6 避免匈牙利命名法和 命名前缀554.1.7 避免相同的名称用于 不同的用途574.2 注释574.2.1 让写代码像讲故事一样574.2.2 不要为易懂的代码写注释584.2.3 不要通过注释禁用代码594.2.4 不要写块注释594.2.5 特殊情况的注释是有用的624.3 函数664.3.1 只做一件事情684.3.2 让函数尽可能小694.3.3 函数命名704.3.4 使用容易理解的名称714.3.5 函数的参数和返回值724.4 C 项目中的C风格代码834.4.1 使用C 的string和stream来 替代C风格的char*834.4.2 避免使用printf()、sprintf()、 gets()等854.4.3 使用标准库的容器而不是使用 C风格数组884.4.4 使用C 类型转换代替C风格 类型转换914.4.5 避免使用宏92第5章 现代C 的高级概念955.1 资源管理955.1.1 资源申请即初始化975.1.2 智能指针985.1.3 避免显式的new和delete1045.1.4 管理专有资源1055.2 move语义1065.2.1 什么是move语义1075.2.2 左值和右值的关系1085.2.3 右值引用1095.2.4 不要滥用move语义1115.2.5 零原则1115.3 编译器是你的搭档1155.3.1 自动类型推导1165.3.2 编译时的计算1195.3.3 模板变量1215.4 不允许出现未定义行为1235.5 Type-Rich编程1245.6 熟悉使用的库1325.6.1 熟练使用1335.6.2 使用Boost1405.6.3 应该了解的其他库1415.7 正确处理异常和错误1425.7.1 防患于未然1425.7.2 从字面上讲,例外就是异常1465.7.3 如果不能恢复,则尽快退出1475.7.4 用户自定义异常1485.7.5 值类型抛出,常量引用类型 捕获1495.7.6 注意catch的正确顺序1505.8 接口设计1505.8.1 Attribute1515.8.2 concept:模板参数的要求155第6章 模块化编程1596.1 模块化的基础1606.1.1 模块设计的原则1606.1.2 小结1626.2 面向对象1636.2.1 面向对象思想1646.2.2 类的设计原则1656.3 模块2006.3.1 #include的缺点2006.3.2 使用模块来解决2026.3.3 底层实现2036.3.4 使用模块的三种方案2046.3.5 模块的影响207第7章 函数式编程2087.1 什么是函数式编程2097.1.1 什么是函数2107.1.2 纯函数和非纯函数2117.2 现代C 中的函数式编程2127.2.1 基于模板的函数式编程2127.2.2 仿函数2147.2.3 绑定包装和函数包装2217.2.4 Lambda表达式2237.2.5 通用Lambda表达式2257.2.6 Lambda模板2267.3 高级函数2287.4 管道与范围适配器2337.5 整洁的函数式编程代码236第8章 测试驱动开发2388.1 传统单元测试的缺点2398.2 作为颠覆者的测试驱动开发2408.2.1 TDD的流程2408.2.2 TDD示例:罗马数字的