By Herb Sutter, Andrei Alexandrescu 著
树人 译编码风格
14. 优先使用编译时和链接时错误,而不是运行时错误。
不要把可以在构建时做的事情推迟到运行时来做:优先编写那些在编译阶段利用编译器来检查不变量的代码,而不是在运行时来检查它们。运行时检查时控制和数据是独立的,也就是说你不能彻底地了解它们。相反,编译时检查是非控制和数据独立的,而且它还能提供更高等级的可信任度。
15. 优先使用const。
const是好朋友:不可变的值更容易理解,跟踪和解释。所以呢,当变量很敏感时要优先使用常量,当你定义一个值的时候把const作为默认的选择。它很安全,在编译时检查(参见Item14),而且它还和C++的类型系统集成在一起。不要轻易去除const限定,除非是调用一个const-incorrect函数。
16. 避免使用宏。
坦率地说:宏是C和C++的抽象设施中最生硬的工具,披着函数外壳的贪婪的狼,很难被驯服,出没于你的所有作用域。要避免它!
17. 避免使用奇异数(magic number)。
程序设计并不奇异,所以不要去诅咒它:避免在代码中出现像41或3.14159这样的文字常量。它们不具备自我解释能力,而且有着非常复杂的维护能力(增加了一种很难被探测到的重复代码形式)。使用诸如width * aspectRatio的符号名或表达式来代替。
18. 尽可能局部化变量的声明。
避免作用域的膨胀,对需求和变量也是一样:变量引入一个状态,你应该处理尽可能少的状态和尽可能短的生命期。这是一个值得单独对待的一个特殊的Item10的例子。
19. 始终要初始化变量。
改过自新:在C和C++程序中,未初始化的变量是一个常见的bug来源。可以通过在使用前清理内存来避免这类bug;在变量定义时进行初始化。
20. 避免长方法(函数)。避免深层的嵌套。
短比长好,平比深好:过于长的函数和嵌套过深的代码块通常都是由于没有赋予一个函数一个内聚的责任(参见Item5)而引起的,通常可以通过更好的重构来解决。
21. 避免跨编译单元的初始化相关性。
保持(初始化)顺序:在不同编译单元中的名字空间级对象的初始化绝不能相互依赖,因为它们初始化的顺序是未定义的。否则,会引起令人头疼问题,从不可思议的崩溃(当你做很小的变更时)到严重的不可移植性(即使是同一编译器的新的发布)。
22. 最小化定义相关性。避免循环相关性。
不要过度依赖:当一个前向声明就可以满足要求时,不要去#include一个定义。
不要相互依赖:循环依赖性发生在两个直接或间接相互依赖的时候。一个模块就是一个发布的内聚单元;那些相互依赖的模块并非真的是单独的模块,但可以粘在一起组成一个更大的模块,一个更大的发布单元。
因此,循环相关性是和模块化相冲突的,而且它也是大型工程的祸根。要避免它们!
23. 让头文件自给自足。
Behave responsibly:通过包含其内容所依赖的任何头文件来确保你写的每个头文件都是编译独立的。
24. 总是写内部#include防护。决不要写外部#include防护。
穿上头文件的保护装:通过对所有的头文件使用具有唯一名字的#inlcude防护,避免无故的多重包含。