标题：Exceptional C++：47个C++工程难题、编程问题和解决方案（中文版）
图书信息
传世经典书丛
《Exceptional C++：47个C++工程难题、编程问题和解决方案（中文版）》[1]
[美]Herb Sutter 著  Exceptional C++
聂雪军 译
ISBN 978-7-121-17085-0
2012年6月出版
定价：59.00元
16开
276页
传承大师智慧 领悟技术本真
经典名著 翻译良品 典藏不二之选
内容简介
本书讲述如何用标准C++进行企业级的软件开发，通过“问题/解答”的方式，启发读者思考，帮助了解隐藏在问题背后的设计思想，以及各种编程指导原则适用的场合。本书列出的条款涵盖了许多方面的主题，尤其对异常安全性、类和模块的合理设计，正确的代码优化，以及编写符合C++标准的可移植代码进行了深入的讨论。
本书适于有一定C++编程基础的读者阅读。
译者序
得知本书要再版，心里很是高兴。2006年翻译完本书时，还在忐忑地等待女儿出生；而今再版，女儿都已经快5岁了，不由感叹时光荏苒，如白驹过隙。在这5年时间里，C++语言本身并无太大突破，或许最令人期待的就是——最新的C++编程语言国际标准（C++ 0x，或者说C++ 2011）将于今年夏天正式发布，历时8年的C++标准修订工作有望最终完成。新标准对并行编程、Labdam表达式以及右值引用等特性的支持，将进一步提升C++的强大功能。
本书是一本颇具分量的C++经典著作，其特点在2006年版译序中有详细的说明。在此次对译稿的重新修订过程中，完成的工作主要包括：
内容勘误
2006年本书出版后，陆续有读者指出书中存在一些翻译有误或者不到位的地方。在这次修订过程中，我收集了读者通过网上论坛、E-mail等提交的反馈，以及自己平时与同事交流中收到的反馈，一并对其中的错漏之处进行了修正。
语言提炼
在收集到的意见中，有不少读者反映翻译的表述有些拖沓，应该更简练一些。当年自己觉得似乎并无不妥，然而在时隔5年后，当我从旁观者的角度再次阅读2006年的译稿时，发现在行文上确实有些啰嗦，读起来颇为不顺，看来真的是“当局者迷，旁观者清”。因此，借这次修订的机会，我对译稿的语言重新进行组织，尽可能提高文字的简洁性，并确保内容的精确性。在修订完后重新统计，居然比2006年译稿精简了约4千字，不禁汗颜。
在重新修订本书时，我试着把书中47个条款的问题重新解答了一遍，结果发现仍有不少问题没有拿到满分。而且，经历了5年的C++编码实践和沉淀后，看待问题的角度和深度也与5年前大有区别，对相同问题又有了新的理解和认识，正可谓“温故而知新”。这也是我在修订过程中的最深体会，希望无论新读者还是老读者都能从本书中再次有所收获。
本书与More Exceptional C++和Exceptional C++ Style同属Herb Sutter撰写的C++经典系列，读者在阅读本书的同时，可以与其他两本书的内容结合起来，相互补充，举一反三，这对进一步提高自己的C++编程能力是非常有益的。
在经过这次修订后，译稿的质量或有进一步提高，但其中难免还有不妥或者疏漏的地方，欢迎各位读者随时反馈与指正。
对本书的评价，可一言以蔽之：经典之作，历久弥新。
聂雪军
2011年5月于武汉
译者原序
这是一本大师级的C++书籍。
成为一名大师，是每个C++程序员的梦想。在经过了几年的实践之后，许多程序员都能在日常工作中很好地应用C++来解决编程问题和实现功能模块。然而，在处理一些较为复杂的问题时，却往往还是会感到有些力不从心。例如，我们很难编写出非常稳定的代码；在设计大型系统时，总会有一些不完善的地方。有时候虽然能够从直觉上感觉到一些东西，但却始终无法找到问题的关键所在，也很难确定该从哪些方面来入手。究其原因，这是因为虽然我们已经掌握了C++，但对于一些深层次的细节，还没有进行深入和细致的研究。对于上述这些问题，本书将会给出很好的解答。
本书主要有以下的特点：
深入性
这是一本颇具深度的书籍，本书对C++的分析深度是很多C++书籍所不能达到的。对于书中的每个主题，作者首先从理论上进行了严谨的论证，然后再给出实际的代码进行全面和细致的分析，基本上做到了详尽无遗。对于每一种应用，作者都非常清楚地解释了为什么要这么做，以及这种做法的使用环境。如果你已经具备了一定的C++基础，那么本书的内容能够使你的C++能力产生质的提升。
拓展性
C++中的一些特性，例如异常安全性，对于编写高质量的程序来说，是非常必要的。但遗憾的是，到目前为止，了解并使用这些特性的程序员还是不多的。大多数的程序员都还是停留在一些普通的C++特性上，而很少会去研究C++的高级特性。本书对一些C++的高级特性进行了详细的阐述和分析，特别指出了在哪些情况下，这些特性的优势能够得到最大的发挥，以及这些特性能够为我们带来怎样的好处。对这些高级特性的学习，不仅能够使我们从更全面的角度来看待问题，而且也能为我们拓展新的设计思路。
纠错性
在学习C++的过程中，我们免不了会犯一些错误，例如对继承的过度使用，好像“没有大量继承的OO就不是OO”，而我们自己是很难发现这些错误的。久而久之，你会不知不觉地陷入一些思维陷阱中，并因此养成不好的编程习惯。本书的一大特点就是，在分析问题的同时，还指出了一些不好的编程习惯和常见的错误，并且解释了为什么这些做法是不好的和错误的。在阅读了这部分内容之后，你肯定会发现其中有些错误是自己原来没有觉察到的，并且在今后的工作中，也会有意识地去改正这些错误。
对于本书的翻译工作，我投入了大量的时间和精力，工作到凌晨是常有的事情。在翻译的过程中，对于每一个难以理解的地方，我首先保证自己充分地理解，然后再用浅显的语言表达出来，帮助读者更快、更准确地理解书中的内容。由于本人的时间和水平有限,4翻译中的疏漏和错误在所难免,4还望读者和同行不吝指正。
书山有路勤为径，只有让自己不断地学习，不断地提高，成为大师的梦想才有可能实现。祝愿所有的C++程序员都能实现自己的梦想。
致谢
首先要感谢出版方对于我的信任和耐心，使得我能够顺利地完成本书的翻译。在翻译本书的同时，妻子云兰正在准备着迎接我们的第一个孩子，感谢你和未出世的孩子，你们是我所有的动力。感谢我的父母，你们一直都在默默地支持着我。
聂雪军
2006年8月于北京
推荐序
这是一本非常出色的书，当我差不多阅读完全书后，才深刻意识到这本书的巨大价值。本书或许是第一本为那些对C++已经很熟悉的人们——了解C++的全部特性的人们——所写的书。从语言特性到标准库中的组件，再到编程技术，本书的内容安排方式是从一个主题直接跳到另一个主题，这不仅可以使读者的思维处于某种活跃状态，还可以始终保持注意力。这与编写C++程序时遇到的情况是一样的。在本书中，我们将讨论一些相互关联的C++特性，例如类的设计与虚函数的行为，迭代器约定与名字查找规则，赋值运算符函数与异常安全性，编译依赖性与导出模板等。这些讨论涵盖了语言特性、标准库组件和编程技术等多方面的内容，不仅丰富，而且精彩。
我将GotW 读作“Gotcha”，这听起来似乎比较合适。当我把自己对书中问题的解答与Sutter给出的解答相对照时，总会发现自己掉入了他（和C++）设置的陷阱中，虽然不太情愿面对这一情况，但事实确实如此。每当我犯错时，似乎都看到Herb在微笑地说着“Gotcha!”。有些人可能认为这是因为我对C++了解得不多，还有一些人可能认为这是因为C++太复杂了，不易掌握。而我的看法是，这正好说明了当使用C++进行编程时，必须对代码进行细致的思考。C++是一种功能强大的语言，它能够帮助我们解决一些很复杂的问题，因此开发人员一定要尽可能从细处入手去研究这门语言及其标准库，以及惯用编程模式等方面。本书讨论主题的广度，以及独特的“问题/解答”内容组织方式，都将能帮助你做到这一点。
在C++新闻组上，有经验的读者都知道，要选出一位“每周大师”是非常困难的，而亲身参与其中的人们则会有着更深的体会。虽然在网上每周只能产生一位大师，但在本书的帮助下，你很有希望在每次编程时都能写出大师级的代码。
Scott Meyers
1999年6月
序
Exceptional C++通过实例来阐述如何实现可靠的软件开发。本书收录了广受欢迎的网上专栏Guru of the Week（或者简称为GotW）中前30个问题并对它们进行扩充，此外还补充了大量的其他材料。Guru of the Week论述了一系列完整的C++软件开发问题及其解决方案，这些内容很好地阐释了一些特殊的设计技术和编码技术。
本书并不是编码难题的集合，其目的是为了指导程序员如何正确地使用C++来实施企业级的软件设计。本书使用了“问题/解答”这种形式来组织内容，因为我认为这是最有效的学习方法。通过这种方法可以使你了解隐藏在问题背后的设计思想，以及各种指导原则的适用场合。虽然本书列出的条款涵盖了许多方面的主题，但你会注意到，有一些与企业级开发问题相关的主题将重复出现，特别是异常安全性、类和模块的合理设计，正确的代码优化，以及编写符合C++标准的可移植代码。
我希望本书的内容能对你的日常工作有所帮助。此外，我还希望你能从本书中发现一些好的思维方式和编码技术，并且在阅读本书时会不时地发出“啊，太棒了”这样的感叹。毕竟，软件工程不见得是枯燥乏味的。
如何阅读本书
我假设你已经较好地掌握了C++的基本知识。如果还没有的话，那么应该首先去阅读一本优秀的C++入门书籍（可以选择一些经典的著作，例如Bjarne Stroustrup的The C++ Programming Language，Third Edition 或者Stan Lippman与Josee Lajoie合著的C++ Primer, Third Edtion ），然后再阅读一本介绍编程风格的书籍，例如Scott Meyers的经典著作Effctive C++ （我发现通过浏览器来阅读电子书非常方便、有用）。
本书的每个条款都通过一个问题来引出，每个条款都有一个介绍性的标题，如下所示：
条款##：条款的标题 难度系数：X
通过条款的标题和难度系数（通常是在3到91/2之间的值，最大值为10），就可以大致了解将要学习的内容。注意，这里的难度系数是基于我个人的理解给出的，因为我认为这个难度系数对于大多数人来说都比较合适。因此，你可能会发现某个难度系数为7的问题可能会比难度系数为5的问题要容易些。尽管如此，当你看到难度系数为91/2的问题时，最好还是做好充分准备。
你可以不按照章节顺序来阅读书中的内容和问题讨论，但在本书中有几个地方介绍的是“一系列”相关的问题，在讲解这些问题的条款的标题中将出现“之一”“之二”等字眼——在有的系列中甚至出现了“之十”。对于这些系列来说，最好将它们作为一个整体来阅读。
本书还提出了许多指导原则，下面这些术语如在指导原则中出现，则有着特殊的含义。
始终（always）：该指导原则是绝对必要的，应该永远都这么做。
优先（prefer）：该指导原则通常是正确的，只有在特定情况下才不适用。
考虑（consider）：该指导原则或许适用，或许不适用，需要视具体情况而定。
避免（avoid）：该指导原则通常不是最好的，甚至可能是危险的。因此，应该去寻求其他的替代方法，并且只有在特殊情况下才应用这条指导原则。
从不（never）：该指导原则非常糟糕，甚至无须考虑就可以直接拒绝使用。
最后，我还想再说一下书中的URL——网上的资料始终在不断地变化和更新，特别是有些资料的变化和更新是我无法控制的。我们通常会赶在书籍印刷之前将这些网页URL加入书中，以免这些URL失效；而当书籍被印刷出来并且在你的桌子上放了5年之后，这些URL的有效性就没人关心了，这是很痛苦的事情。因此，当我需要在书中引用其他人的文章或者网址时，将通过我自己站点gotw上的URL来引用，并且站点上的这些链接只是包含了到真实网页的重定向，这样就能够控制URL的有效性。当你发现本书中的某个链接不再有效时，那么请发E-mail告诉我，我将更新链接并重定向到新的网址（如果我还能找到这些网页）或者说明这些URL不再有效（如果找不到的话）。通过这种方法，无论书籍的印刷媒介是什么，书中的URL都是最新的。
本书的缘由：GotW和PeerDirect
C++ Guru of the Week这个系列已经经历了很长的一段发展历程。GotW最初是在1996年底创建的，用来为我们自己在PeerDirect公司的开发小组提供一些有趣的难题和学习课程。我编写这个系列的目的是为了提供一种有趣的学习工具，内容包括如何合理地使用继承以及异常安全性。随着时间的推移，我还通过这个系列将C++标准会议上做出的一些修改告诉小组成员。此后，GotW就向普通的C++程序员开放，并被作为网上新闻组comp.lang.c++.moderated上的一个固定专栏，在这个新闻组中可以找到每一期的问题和解答（以及许多有趣的讨论）。
在PeerDirect公司里，用好C++很重要，这与在其他公司中用好C++的理由是相同的，只不过所要实现的目标会有所不同。我们的主要工作是构建系统软件——包括分布式数据库以及数据库的复制——其中像可靠性、安全性、可移植性、执行效率以及其他一些因素都是非常重要的。我们所编写的软件必须能够在多种不同的编译器和操作系统上进行移植；当发生数据库事务死锁、通信中断或者程序异常时，这些软件必须是安全的和健壮的。用户可以使用这些软件来管理位于智能卡、自动售卖机或者PalmOS和WinCE设备上的微型数据库，部门级的Windows NT、Linux和Solaris服务器，以及支撑网页服务器和数据仓库的大规模并行Oracle后台服务——我们实现这些功能时使用的是相同的软件、相同的可靠性和相同的代码。当编写大量紧凑并且没有注释行的代码时，可移植性和可靠性将是要面临的巨大挑战。
对于在过去几年中一直在网上阅读Guru of the Week系列的读者，我想声明两件事情：
感谢你们的关注、支持、E-mail、赞赏、更正、意见、批评和问题——特别是你们希望将GotW系列汇编成书的要求。现在这本书已经完成了，希望你们能够喜欢。
本书包含的内容要远远多于在网上给出的内容。
本书并不只是对网上原有的GotW问题进行简单的复制和粘贴，而是对所有问题和解答都进行了很大程度的修正和重新整理——例如，在条款8到条款17中关于异常安全性的讨论，最初只是一个单独的GotW问题，而现在已经变成了一个更为深入的，并且拥有10个条款的系列。每个问题和解答都经过了仔细的检查，确保与现在正式的C++标准保持一致。
因此，如果你以前是GotW的固定读者，那么在本书中仍然会看到大量新的内容。再次感谢所有忠实的读者，另外，我希望本书还可以帮助你不断地提升和扩充自己在软件工程和C++编程等方面的技术。
致谢
首先要感谢在comp上所有的GotW热心读者，尤其是那些参与为本书取名的人们。特别感谢两位对本书的最终名字有很大帮助的读者：Macro Dalla Gasperine（建议的名字是Enlightented C++）；Rob Stewart（建议的名字是Practical C++：Problems and Solutions）。由于我在本书中反复强调了异常安全性，因此在这些名字的基础上，我很自然地使用了“Exceptional”这个单词。
我还要感谢丛书的编辑Bjarne Stroustrup，感谢Marina Lang，Debbie Lafferty以及其他Addison Wesley Longman出版公司的工作人员，感谢他们对本书的兴趣和热情，并感谢他们在1998年Santa Cruz召开的C++标准会议上举行的招待会。
我还要感谢许多审阅本书的人们——其中许多人都是C++标准委员会的成员——他们提出了许多成熟而深刻的建议，这些建议对于本书的内容起到了很大的改进作用。特别感谢Bjarne Stroustrup，Scott Meyers，Andrei Alexandrescu，Steve Clamage，Steve Dewhurst，Cay Horstmann，Jim Hyslop，Brendan Kehoe以及Dennis Mancl，感谢他们宝贵的观点和意见。
最后，我最需要感谢的是我的家人和朋友，他们通过各种各样的方式始终陪伴着我。
Herb Sutter
1999年6月
目 录
1 泛型程序设计与C++标准库1
条款1：迭代器难度系数1
条款2：大小写不敏感的字符串——之一5
条款3：大小写不敏感的字符串——之二9
条款4：可重用性最高的泛型容器——之一12
条款5：可重用性最高的泛型容器——之二13
条款6：临时对象22
条款7：标准库的使用（或者，再论临时对象）28
2 异常安全性相关的问题与技术31
条款8：编写异常安全的代码——之一32
条款9：编写异常安全的代码——之二37
条款10：编写异常安全的代码——之三40
条款11：编写异常安全的代码——之四47
条款12：编写异常安全的代码——之五50
条款13：编写异常安全的代码——之六56
条款14：编写异常安全的代码——之七62
条款15：编写异常安全的代码——之八65
条款16：编写异常安全的代码——之九68
条款17：编写异常安全的代码——之十73
条款18：代码的复杂性——之一75
条款19：代码的复杂性——之二79
3 类的设计与继承85
条款20：类的编写技巧85
条款21：虚函数的重载93
条款22：类之间的关系——之一99
条款23：类之间的关系——之二103
条款24：继承的使用和滥用110
条款25：面向对象程序设计121
4 编译器防火墙和Pimpl惯用法123
条款26：将编译期依赖性降到最低——之一123
条款27：将编译期依赖性降到最低——之二127
条款28：将编译期依赖性降到最低——之三132
条款29：编译防火墙135
条款30：Fast Pimpl惯用法138
5 名字查找、名字空间和接口规则148
条款31：名字查找与接口规则——之一148
条款32：名字查找与接口规则——之二152
条款33：名字查找和接口规则——之三162
条款34：名字查找与接口规则——之四167
6 内存管理176
条款35：内存管理——之一176
条款36：内存管理——之二179
条款37：AUTO_PTR186
7 误区、陷阱以及错误的惯用法201
条款38：对象标识201
条款39：自动转换204
条款40：对象的生存期——之一206
条款41：对象的生存期——之二209
8 其他主题219
条款42：变量的初始化219
条款43：正确使用const222
条款44：类型转换231
条款45：BOOL238
条款46：转调函数242
条款47：控制流程244
后记254
参考书目256