C++ 代码整洁的基本规范

Written by - kok-s0s

C++

良好的命名

程序,是为了供人阅读而编写的,只是顺便提供给机器执行。--- Hal Abelson and Gerald Jay Sussman, 1984

源代码文件、命名空间、类、模板、函数、参数、变量和常量等,都应该具有有意义且富有表现力的名字。

名称应该自解释

所谓代码自解释,就是不需要注释解释其用途的代码。

使用简单但是具有自我解释和自我描述的命名。

使用域中的名称

领域驱动设计(Domain-Driven Design,DDD)

DDD 是接近于复杂面向对象开发的一种方法,主要集中在核心领域和领域逻辑上。领域驱动设计是试图通过将业务领域的事物和概念映射到代码中,使你的软件成为一个真实系统的模型。

领域驱动设计能够帮助软件开发团队在公司的业务和 IT 利益相关人之间创建一个通用的模型,开发团队可以用这个通用模型来沟通业务需求、数据实体模型和过程模型。

将应用程序域的元素和概念作为一个方式去命名组件、类和概念,能让开发者自然地表达软件设计的思想。

选择适当抽象层次的名称

避免冗余的名称

避免晦涩难懂的缩写

为变量或常量取名称的时候,请使用完整单词而不是晦涩难懂的缩写。原因很明显:那些晦涩难懂的缩写会显著降低代码的可读性,此外,当开发人员谈论他们的代码时,变量名称也应该很容易发音。

避免匈牙利命名法和命名前缀

避免相同的名称用于不同的目的

注释

真相只能在一个地方找到,代码。--- Robert C.Martin,Clean Code [Martin09]

在大多数情况下,注释就是代码异味(code smell)。

当需要解释和澄清代码功能时,注释是必要的,但这通常意味着开发人员不能编写出简单且能够自解释的代码。

让写代码像讲故事一样

代码应讲述一个故事并且能自解释,必须尽可能避免注释。

任何程序员都能写出计算机能够理解的代码;而优秀的程序员能够编写人类可以理解的代码。--- Martin Fowler,1999

不要为易懂的代码写注释

不要通过注释禁用代码

除了快速进行测试外,不要通过注释禁用代码,同时还要有一个版本控制系统!

不要写块注释

特殊情况的注释是很有用的

函数

函数(方法、程序、服务、操作)是任何软件系统的核心,它们代表代码行之上的第一个组织单位。编写良好的函数可以显著提高程序的可读性和可维护性。出于这个原因,它们应该被精心设计并被谨慎对待。

圈复杂度

定量软件度量圈复杂度是由美国数学家 thomas J.McCabe 于 1976 年发明的。 该度量直接计算一段源代码的线性独立路径的数量,例如函数。如果函数不包含 if 或 switch 语句,并且没有 for 或 while 循环,则只有一条通过函数的路径,圈复杂度为 1。如果函数包含一条表示单个决策点的 if 语句,则有两条通过函数的路径,圈复杂度为 2。 如果圈复杂度很高,受影响的代码通常更难以理解、测试和修改,因此更容易出问题。

只做一件事情

函数应该做一件事情,应该做好这件事情,应该仅做好这一件事情。--- Robert C.Martin,Clean Code [Martin09]

一个函数,必须有一个定义非常清晰的任务或功能,它应该用它的函数签名(函数型构)来表示。

函数做了太多事情的样子:

  1. 函数体量比较大,也就是说,一个函数包含了很多代码行。

  2. 当你试图为这个函数找到一个有意义和有表现力的名字以描述该函数的功能时,函数名字中无法避免地使用连词,例如,“和”、“或”。

  3. 函数体用空行垂直分隔成代表后续步骤的几个片段,通常,这些片段的开头使用注释说明这些代码片段的功能。

  4. 圈复杂度比较高,函数包含了太多的 if、else 或 switch-case 语句。

  5. 函数的入参比较多,特别是一个或多个 bool 类型的参数。

让函数尽可能小

函数应该很小,理想情况下是 4 ~ 5 行,最多 12 ~ 15 行,行数不能再多了。

函数命名

函数名称应以动词开头。谓词,即关于一个对象是 true 或 false 的陈述,应该以 ishas 开头。

使用容易理解的名称

函数的名称应表达其意图和目的,而不是解释它的工作原理。

函数的参数和返回值

  1. 参数的个数

函数的参数应该尽可能的少。一个参数是比较理想的,类的成员函数(方法)一般没有参数。通常这些函数被用于操作对象的内部状态,或者被用于从对象中查询某些内容。

  1. 避免使用标志参数

bool 类型

枚举类型

  1. 避免使用输出参数

不惜一切代价也要避免使用输出参数。

  1. 不要传递或返回 0(NULL、nullptr)

如果从函数或方法返回常规指针是不可避免的,不要返回 nullptr!

如果不可避免地处理指向资源的指针,请使用智能指针。

  1. 正确地使用 const

C++ 工程中的 C 风格代码

使用 C++ 的 string 和 stream 替代 C 风格的 char*

避免使用 printf()、sprintf() 和 gets() 等

使用标准库的容器而不是 C 风格的数组

用 C++ 类型转换代替 C 风格的强制转换

避免使用宏

Top