第1章 简介 1
1.1 软件熵 2
1.2 整洁的代码 4
1.3 为什么使用C++ 4
1.4 C++11——新时代的开始 5
1.5 适合本书的读者 5
1.6 本书使用的约定 6
1.6.1 扩展阅读 6
1.6.2 说明、提示和警告 6
1.6.3 示例代码 7
1.6.4 编码风格 7
1.7 相关网站和代码库 7
1.8 UML图 8
第2章 构建安全体系 9
2.1 测试的必要性 9
2.2 测试入门 11
2.3 单元测试 13
2.4 关于QA 15
2.5 良好的单元测试原则 16
2.5.1 单元测试的代码的质量 16
2.5.2 单元测试的命名 16
2.5.3 单元测试的独立性 17
2.5.4 一个测试一个断言 18
2.5.5 单元测试环境的独立初始化 19
2.5.6 不对getters和setters做单元测试 19
2.5.7 不对第三方代码做单元测试 20
2.5.8 不对外部系统做单元测试 20
2.5.9 如何处理数据库的访问 20
2.5.10 不要混淆测试代码和产品代码 21
2.5.11 测试必须快速执行 23
2.5.12 测试替身 24
第3章 原则 27
3.1 什么是原则 27
3.2 保持简单和直接原则(KISS) 28
3.3 不需要原则(YAGNI) 29
3.4 避免复制原则(DRY) 29
3.5 信息隐藏原则 30
3.6 高内聚原则 33
3.7 松耦合原则 35
3.8 小心优化原则 38
3.9 最少惊讶原则(PLA) 39
3.10 童子军原则 39
第4章 C+代码整洁的基本规范 41
4.1 良好的命名 42
4.1.1 名称应该自解释 43
4.1.2 使用域中的名称 45
4.1.3 选择适当抽象层次的名称 45
4.1.4 避免冗余的名称 46
4.1.5 避免晦涩难懂的缩写 47
4.1.6 避免匈牙利命名和命名前缀 47
4.1.7 避免相同的名称用于不同的目的 48
4.2 注释 49
4.2.1 让写代码像讲故事一样 49
4.2.2 不要为易懂的代码写注释 50
4.2.3 不要通过注释禁用代码 50
4.2.4 不要写块注释 51
4.2.5 特殊情况的注释是有用的 53
4.3 函数 56
4.3.1 只做一件事情 59
4.3.2 让函数尽可能小 59
4.3.3 函数命名 61
4.3.4 使用容易理解的名称 61
4.3.5 函数的参数和返回值 62
4.4 C++工程中的C风格代码 72
4.4.1 使用C+++的string和stream替代C风格的char* 73
4.4.2 避免使用printf()、sprintf()和gets()等 74
4.4.3 使用标准库的容器而不是C风格的数组 77
4.4.4 用C+++类型转换代替C风格的强制转换 80
4.4.5 避免使用宏 81
第5章 现代C+的高级概念 83
5.1 资源管理 84
5.1.1 资源申请即初始化 85
5.1.2 智能指针 86
5.1.3 避免显式的new和delete 92
5.1.4 管理特有资源 92
5.2 Move语义 94
5.2.1 什么是Move语义 94
5.2.2 左值和右值的关系 95
5.2.3 右值引用 96
5.2.4 不要滥用Move 97
5.2.5 零原则 98
5.3 编译器是你的搭档 102
5.3.1 自动类型推导 102
5.3.2 编译时计算 105
5.3.3 模板变量 107
5.4 不允许未定义的行为 108
5.5 Type-Rich编程 110
5.6 了解你使用的库 116
5.6.1 熟练使用〈algorithm〉 116
5.6.2 熟练使用Boost 121
5.6.3 应该了解的一些库 121
5.7 恰当的异常和错误处理机制 122
5.7.1 防患于未然 123
5.7.2 异常即异常——字面上的意思 126
5.7.3 如果不能恢复则尽快退出 128
5.7.4 用户自定义异常 128
5.7.5 值类型抛出,常量引用类型捕获 130
5.7.6 注意catch的正确顺序 130
第6章 面向对象 131
6.1 面向对象思想 132
6.2 抽象——解决复杂问题的关键因素 133
6.3 类的设计原则 134
6.3.1 让类尽可能小 134
6.3.2 单一职责原则(SRP) 135
6.3.3 开闭原则(OCP) 135
6.3.4 里氏替换原则(LSP) 136
6.3.5 接口隔离原则(ISP) 146
6.3.6 无环依赖原则 148
6.3.7 依赖倒置原则(DIP) 151
6.3.8 不要和陌生人说话(迪米特法则) 156
6.3.9 避免“贫血类” 160
6.3.10 只说不问 160
6.3.1 1避免类的静态成员 162
第7章 函数式编程 164
7.1 什么是函数式编程 165
7.1.1 什么是函数 166
7.2.2 pure函数和impure函数 167
7.2 现代C++中的函数式编程 168
7.2.1 C+++模板函数编程 168
7.2.2 仿函数 170
7.2.3 绑定和函数包装 176
7.2.4 Lambda表达式 178
7.2.5 通用Lambda表达式(C+++14) 180
7.3 高阶函数 181
7.4 整洁的函数式编程代码 186
第8章 测试驱动开发 188
8.1 普通的旧单元测试的缺点 189
8.2 测试驱动开发作为颠覆者 190
8.2.1 TDD的流程 190
8.2.2 TDD的一个小例子:Code Kata 193
8.3 TDD的优势 210
8.4 什么时候不应该使用TDD 212
第9章 设计模式和习惯用法 213
9.1 设计原则与设计模式 214
9.2 常见的设计模式及应用场景 214
9.2.1 依赖注入模式 215
9.2.2 Adapter模式 226
9.2.3 Strategy模式 227
9.2.4 Command模式 231
9.2.5 Command处理器模式 235
9.2.6 Composite模式 238
9.2.7 Observer模式 241
9.2.8 Factory模式 245
9.2.9 Facade模式 248
9.2.10 Money Class模式 249
9.2.11 特例模式 252
9.3 什么是习惯用法 255
附录A UML简要指南 266
参考文献 275