在国际象棋中,学习走子的规则仅是第一步,要想精通则必须理解走动每一步棋的技巧和策略,而这也同样适用于C++。知道了正确的C++策略,有助于避免编程陷阱,以及更加有效地工作。杰出的C++专家Robert B. Murray在《C++编程惯用法——高级程序员常用方法和技巧》中与初级和中级C++程序员分享了他多年积累的经验和建议。
本书使用大量的示例代码演示有用的编程策略,并对一些危险的做法提出了警告。为了帮助读者进一步理解,本书每章末尾都会列出这一章介绍的重要思想,同时还会提出一些问题帮助读者思考和讨论。
本书首先讲解了如何选择正确的抽象,以及谨慎保存抽象和实现之间的区别,然后介绍了将一个抽象转换为一个或多个C++类的过程,并讨论了高层次的设计策略以及低层次的接口和实现细节。
在Robert B.Murray所著的《C++编程惯用法——高级程序员常用方法和技巧》中,C++专家Robert B. Murray与我们分享了他宝贵的经验和建议,以帮助初中级C++程序员得到进一步的提高。
《C++编程惯用法——高级程序员常用方法和技巧》总共分为11章,先后介绍了抽象、类、句柄、继承、多重继承、考虑继承的设计、模板的高级用法、重用、异常以及向C++的移植等相关的诸多话题。在书中,作者大量采用了实际开发中的代码作为示例,向读者展示了那些有用的编程策略,并对那些有害的做法进行了警示。为了帮助读者更好地理解,在每一章结束前,在该章中介绍过的主要内容都被放到了一个列表中,此外,书中还给出了一些问题来激励读者们进行更多的思考和讨论。
《C++编程惯用法——高级程序员常用方法和技巧》适合具有一定C++编程经验的程序员和项目经理阅读,也适合对C++编程的高级主题感兴趣的读者参考。
第1章 抽象 1
1.1 有关电话号码的抽象模型 3
1.2 抽象模型间的关系 5
1.3 请考虑边界条件 10
1.4 使用CRC卡片来辅助设计 10
1.5 小结 11
1.6 问题 11
第2章 类 13
2.1 构造函数 13
2.2 赋值 21
2.3 公用数据 23
2.4 隐式类型转换 27
2.5 操作符重载:成员或非成员? 33
2.6 重载、缺省值以及省略符 35
2.7 Const 37
2.8 返回值为引用 44
2.9 静态对象的构造 44
2.10 小结 46
2.11 问题 46
第3章 句柄 49
3.1 一个String类 49
3.2 使用计数器来避免多份拷贝 51
3.3 避免进行重编译:Cheshire Cat 56
3.4 使用句柄来隐藏设计 58
3.5 多种实现 59
3.6 作为对象的句柄 63
3.7 综述 63
3.8 小结 63
3.9 问题 64
第4章 继承 67
4.1 is-a关系 67
4.2 公有继承 72
4.3 私有继承 73
4.4 保护型继承 75
4.5 与基类抽象的一致性 75
4.6 纯虚函数 78
4.7 有关继承的细节和陷阱 80
4.8 小结 83
4.9 问题 84
第5章 多重继承 85
5.1 作为交集的多重继承 85
5.2 虚基类 89
5.3 一些有关多重继承的细节问题 93
5.4 小结 95
5.5 问题 95
第6章 考虑继承的设计 97
6.1 被保护的接口 97
6.2 我们的设计是否应该考虑到继承? 101
6.3 一些为继承所做的设计的例子 105
6.4 结论 111
6.5 小结 111
6.6 问题 111
第7章 模板 113
7.1 模板类Pair 115
7.2 一些有关模板的细节 117
7.3 模板的实例化 118
7.4 智能指针 120
7.5 作为模板参数的表达式 126
7.6 模板函数 128
7.7 小结 131
7.8 问题 132
第8章 模板的高级用法 135
8.1 使用了模板的容器类 135
8.2 示例:Block 137
8.3 有关Block的设计细节 140
8.4 带有迭代器的容器:List 144
8.5 迭代器的设计细节 151
8.6 性能上的考虑 154
8.7 对模板参数的限制 157
8.8 模板特化 159
8.9 小结 165
8.10 问题 166
第9章 重用 169
9.1 发现和获得 170
9.2 健壮性 171
9.3 内存管理 177
9.4 可选的内存分配方案 179
9.5 传递参数给operator new 183
9.6 管理外部资源 185
9.7 寻找有关内存的bug 185
9.8 名字冲突 190
9.9 性能 194
9.10 不要去猜想,而应该度量! 194
9.11 算法 195
9.12 动态内存分配中的瓶颈 196
9.13 内嵌 201
9.14 Tiemann法则 203
9.15 小结 204
9.16 问题 205
第10章 异常 207
10.1 一个负面的声明 207
10.2 为什么需要异常? 209
10.3 一个异常的例子 210
10.4 异常只应该用来表述异常情况 211
10.5 理解异常 213
10.6 责任评估 213
10.7 设计异常对象 215
10.8 小结 218
10.9 问题 218
第11章 向C++移植 221
11.1 选择使用C++ 221
11.2 采用C++ 223
11.3 设计和实现 224
11.4 开发一个坚实的基础 227
11.5 相关的思考 227
11.6 小结 227
11.7 问题 228