良好的编程规范可以改善软件质量,缩短上市时间,提升团队效率,简化维护工作。在本书中,两位全世界最受尊敬的 C++ 专家将全球 C++ 社区的集体智慧和经验凝结成一整套编程规范。这些规范可以作为每一个开发团队制定实际开发规范的基础,更是每一位 C++ 程序员应该遵循的行事准则。本书实际上涵盖了 C++ 程序设计的各个方面,包括:设计和编码风格、函数、操作符、类的设计、继承、构造与析构、赋值、名字空间、模块、模板、泛型、异常、 STL 容器和算法等等。书中对每一条规范都给出了言简意赅的叙述,并辅以实例说明;书中还给出了从类型定义到错误处理等方面的大量 C++ 最佳实践,包括许多最新总结和标准化的技术,即使使用 C++ 多年的程序员也会从中受益匪浅。 本书适合于各层次 C++ 程序员,也可作为高等院校 C++ 课程的教学参考书。\r\n 本书涵盖了C++程序设计的方方面面,包括设计和编码风格、函数、操作符、类的设计、继承、构造与析构、赋值、名字空间、模块、模板、泛型、异常、STL容器和算法等。书中对每一条规范都给出了言简意赅的叙述,并辅以实例说明;书中还给出了从类型定义到错误处理等方面大量的C++最佳实践,包括许多最新总结出的和标准化的技术,即使使用C++多年的程序员也会从中受益匪浅。 \r\n 在本书中,两位知名的C++专家将全球C++界20年的集体智慧和经验凝结成一套编程规范。这些规范可以作为每一个开发团队制定实际开发规范的基础,更是每一位C++程序员应该遵循的行事准则。书中对每一条 规范都给出了精确的描述,并辅以实例说明;从类型定义到错误处理,都给出了最佳的C++实践。即使使用C++多年的程序员也会从本书中受益匪浅。 \r\n 本书适合于各层次C++程序员使用,也可作为高等院校C++课程的教学参考书。
组织及策略上的问题(Organizational and Policy Issues)\r\n 0. 不拘小节(或:了解什么不需要被规范化)\r\n 1. 在高警告级别下干净地编译\r\n 2. 使用自动化的构建(build)系统\r\n 3. 使用版本控制系统(version control system)\r\n 4. 在代码复查上投资\r\n设计风格(Design Style)\r\n 5. 给每一个实体分配一份内聚的职责\r\n 6. 以正确,简单,清晰为上\r\n 7. 编程中应知道何时和如何考虑可伸缩性\r\n 8. 不要进行不成熟的优化\r\n 9. 不要进行不成熟的劣化\r\n 10. 尽量减少全局和共享数据\r\n 11. 隐藏信息\r\n 12. 了解何时及如何为并发性编写代码\r\n 13. 确保资源为对象所占有。使用显式的RAII和智能指针\r\n编程风格(Coding Style)\r\n 14. 宁可在编译和链接时出错也不要在运行时出错\r\n 15. 积极使用const\r\n 16. 避免使用宏\r\n 17. 避免使用魔数(magic numbers)\r\n 18. 尽可能局部地声明变量\r\n 19. 总是初始化变量\r\n 20. 避免太长的函数。避免太深的嵌套\r\n 21. 避免跨编译单元的初始化依赖\r\n 22. 尽量减少定义性依赖。避免循环依赖\r\n 23. 头文件应该自给自足\r\n 24. 总是编写内部#include防护符。决不要用外部#include防护符\r\n函数与操作符(Functions and Operators)\r\n 25. 正确地选择通过值、(智能)指针或者引用传递参数\r\n 26. 保持重载操作符的自然语义\r\n 27. 优行使用算术操作符和赋值操作符的标准形式\r\n 28. 优先使用++和--的标准形式。优先调用前缀形式\r\n 29. 考虑重载以避免隐含类型转换\r\n 30. 避免重载&&, ||, 或, (逗号)\r\n 31. 不要编写依赖于函数参数求值顺序的代码\r\n类设计及继承\r\n构造,析构,及复制操作\r\n名字空间与模块\r\n模板与泛型\r\n错误处理与异常\r\nSTL:容器\r\nSTL:算法\r\n类型安全\r\n参考文献\r\n摘要汇总\r\n索引
Herb Sutter 是 ISO C++ 标准委员会主席,《C++ Users Journal》杂志特邀编辑和专栏作家。他目前在微软公司领导 .NET 环境下 C++ 语言扩展的设计工作。除本书外,他还撰写了三本广受赞誉的图书:《Exceptional C++ Style》 (中文版即将由人民邮电出版社出版) 、《Exceptional C++》和《More Exceptional C++》。Andrei Alexandrescu 是世界顶尖的 C++ 专家,《C++ Users Journal》杂志的专栏作家,他的《Modern C++ Design》一书曾荣获 2001 年最佳 C++ 图书称号。书中所开发的 Loki 已经成为最负盛名的 C++ 程序库之一。
尽早进入正轨:以同样的方式实施同样的过程。不断积累惯用法。
将其标准化。如此,你与莎士比亚之间的惟一区别将只是掌握惯用法的多少——而非词汇的多少。
——Alan Perlis
标准最大的优点在于,它提供了如此多样的选择。
——出处尚无定论
我们希望编写本书作为各开发团队编程规范的基础是出于下面两个主要原因:
编程规范应该反映业界最久经考验的经验:它应该包含以经验和对语言的深刻理解为基础的公认的惯用法。具体而言,编程规范应该牢固地建立在大量丰富的软件开发文献的基础之上,收集散布在各种来源的规则、准则和最佳实践。
大自然是憎恶真空的:通常,如果你不能有意识地制定合理的规则,那么很可能会有其他人推行他们自己喜欢的规则集。这样产生的编程规范往往具有各种最不希望出现的属性。例如,许多这样的编程规范都试图强制尽量少地按C语言的方式使用C++。
许多糟糕的编程规范都是由一些没有很好地理解语言、没有很好地理解软件开发或者试图标准化过多东西的人制定的。糟糕的编程规范会很快丧失可信度,最好的情况是,即使其中一些合理的准则也有可能被失去幻想的程序员所忽略,因为他们不喜欢或者不同意其中一些糟糕的准则。这还是“最好的情况”——最坏的情况是,糟糕的标准可能真的被强制执行。
如何使用本书
三思而行。应该认真地遵循好的准则;但是不要盲从。在本书的各条中,请注意“例外情况”部分阐明了该准则可能不适用的不太常见的情况。任何准则,无论如何正确(当然,我们自认为本书中的准则是正确的),都不能代替自己的思考。
每个开发团队都应该制定自己的标准,制定标准的时候都应该尽职尽责。这项工作是整个团队的事情。如果你是团队负责人,应该让团队成员都参与制定标准;人们当然更愿意遵守“自己的”标准,而非一堆他们感觉是别人强加的规矩。
编写本书的目的是为各开发团队提供编程规范的基础和参考。它并不是要成为终极编程规范,因为不同的团队会有适合特定群体或者特定任务的更多准则,应该大胆地将这些准则加入本书的条款中。但是我们希望本书能够通过记载和引用广泛接受的、权威的、几乎可以通用的(“例外情况”指出的除外)实践经验,减少读者制定或重新制定自己的编程规范的工作量,从而帮助提高读者所用编程规范的质量和一致性。
让团队人员阅读这些准则及其原理阐释(也就是本书全文,根据需要还包括所选条款引用的其他书籍和论文),共同决定是否有团队根本无法接受的内容(比如,由于某些项目特殊的情况),然后实践其余规范。一旦采纳,则在未与整个团队协商的情况下,任何人不得违反团队编程规范。
最后,团队还需定期复查这些准则,加入来自实际应用中的经验和反馈。
编程规范与人的关系
好的编程规范能够带来许多相互关联的优点:
改善代码质量:鼓励开发人员一贯地正确行事,从而能够直接提高软件的质量和可维护性。
提高开发速度:开发人员不需要总是从一些基本原则出发进行决策。
增进团队精神:有助于减少在一些小事上不必要的争论,使团队成员更容易阅读和维护其他成员的代码。
在正确的方向上取得一致:使开发人员放开手脚,在有意义的方向上发挥创造性。
在压力和时间的要求下,人们将按所受到的训练行事。他们会求助于习惯。这正是医院的急诊室之所以要雇佣有经验的、训练有素的人员的原因所在,再知识渊博的新手到时候也会手足无措。
作为软件开发人员,我们总是面对着巨大的压力,“要在昨天交付明天的软件”。在进度压力下,我们按所受到的训练和习惯工作。平时不知道软件工程良好实践的(或者不习惯应用这些实践的)马虎程序员,在压力下将编写出更加马虎、错误更多的代码。相反,养成良好习惯并经常按此工作的程序员将保持自己的组织性,快速提交高质量的代码。
本书所介绍的编程规范是集编写高质量C++代码准则之大成。它们是C++社区丰富集体经验的精华总结。这一知识体系中的大量内容,此前要么只能零零碎碎地从不同的书中找到,要么需要依靠口口相传。编写本书的目的就是要将这些知识收集起来,汇成一组简练合理、易于理解、简单易行的规则。
当然,即使有最佳编程规范,还是有人会编写出糟糕的代码。任何语言、过程或者方法皆然。但是,好的编程规范集能够培养超越规则本身的良好习惯和纪律。这种基础一旦打好,就将打开通往更高层次的大门。这里没有捷径可走:在学会写诗之前必须首先扩大词汇量,熟悉语法。我们只希望本书能够对读者所经历的这一过程有所裨益。
我们希望本书适用于各种层次的C++程序员。
如果你是初级程序员,我们希望你能够发现这些规则及其原理阐释有助于理解C++语言对哪些风格和惯用法的支持最为自然。我们为每一规则和准则都提供了简洁的原理阐释和讨论,这是为了鼓励你重在理解,而不是死记硬背。
对于中级或者高级程序员,我们下了很大功夫为每一规则都提供了详细的准确引用列表。这样,你就能够对规则在C++类型系统、语法和对象模型中的来历作进一步的研究。
无论如何,你很可能工作在一个复杂项目的团队中。这正是编程规范的用武之地——你可以使用这些规范将团队统一提高到同一层次,并为代码审查打下基础。
关于本书
我们为本书制定了以下设计目标:
一寸短,一寸强:篇幅极大的编程规范很难被人接受,而短小精悍的才会有人阅读和使用。同样,长的条款容易被人忽视,而短的条款才会被阅读和使用。
每个条款都必须是无可争议的:本书的目的是为了记载已达成广泛共识的标准,而不是凭空发明一些规范。如果有什么准则并非在所有情况下都适用,我们会明确指出(比如用“考虑……”而不是“应该……”来表示),并提供普遍接受的例外情况。
每个条款都必须具有权威性:本书中的准则都有所引用的已出版著作的支持。编写本书的目的也包括提供C++文献的索引。
每个条款都必须有阐述的价值:我们选择不为肯定会做的事情(比如编译器已经强制要求或者检查的事情)或者其他条款已经涵盖的事情定义准则。
例如,“不要返回自动变量的指针/引用”是一个不错的准则,但是我们选择不将它放在本书中,因为我们测试过的所有编译器都会对此发出警告,所以这一问题已经涵盖在更广的第1条中了。
例如,“使用编辑器(或者编译器,或者调试器)”是一个不错的准则,但是你当然会使用这些工具,这是不言自明的;与此相反,我们前四个条款中有两个是关于其他工具的:“使用自动构建系统”和“使用版本控制系统”。
例如,“不要滥用goto语句”是一个很好的条款,但是根据我们的经验,程序员普遍都知道这一点,所以对此毋庸我们多言。
每个条款都遵照下面的格式:
条款标题:最简单而又意味深长的“原音重现”,有助于更好地记忆规则。
摘要:最核心的要点,简要陈述。
讨论:对准则的展开说明。通常包括对原理的简要阐释,但是请记住,原理阐释的主要部分都有意识地留在参考文献中了。
示例(可选):说明规则或者有助于记忆规则的实例。
例外情况(可选):规则不适用的任何(通常是比较罕见的)情况。但是要小心,不要掉入过于匆忙而不加思考的陷阱:“噢,我很特殊,所以这条规则对我的情况并不适用”——这种推理很常见,但是通常都是错的。
参考文献:可以参考其中提到的C++文献的章节,进而获得完整的细节和分析。
每一部分中,我们都会选择推荐一个“最有价值条款”。通常,它是该部分中的第一个条款,因为我们尽量将重要的条款放在每一部分的前面。但是有时候,出于连贯和可读性的考虑,我们不能将重要的条款前置,因此需要采取这样的办法突出它们,以引起特别注意。
致谢
非常感谢丛书主编Bjarne Stroustrup、本书的编辑Peter Gordon 和 Debbie Lafferty,还有Tyrrell Albaugh、Kim Boedigheimer、John Fuller、Bernard Gaffney、Curt Johnson、Chanda Leary-Coutu、Charles Leddy、Heather Mullane、Chuti Prasertsith、Lara Wysong,以及Addison-Wesley团队的其他成员,感谢他们在本书写作过程中给予的协助和坚持。和他们一起工作确实是一种荣幸。
各条款标题中“原音重现”的灵感有许多来源,包括[Cline99]的幽默风格和[Peters99]中经典的“import this”,还有传奇般的Alan Perlis和他被广为引用的杰出格言。
我们特别想感谢在本书技术审阅方面做出贡献的人,他们的工作使本书许多部分增色不少。从选题开始直到最终成稿,丛书主编Bjarne Stroustrup所提出的尖锐而又透彻的意见对本书影响至深。我们要特别感谢Dave Abrahams、Marshall Cline、Kevlin Henney、Howard Hinnant、Jim Hyslop、Nicolai Josuttis、Jon Kalb、Max Khesin、Stan Lippman、Scott Meyers和Daveed V
无封面