C ++中的Google样式指南。 第8部分

第1部分。简介
...
第8部分。命名
第9部分。注释
...



编写代码时,我们都使用代码设计规则。 有时会发明自己的规则,而在其他情况下,会使用现成的样式指南。 尽管所有C ++程序员用英语阅读都比用其母语阅读更容易,但是用后者编写一本手册会更令人愉快。
本文是将C ++中的Google样式指南的一部分翻译成俄语的。
原始文章 (github上的fork), 更新了翻译

命名


编码风格的基本规则是命名。 名称的出现立即(无需搜索广告)告诉我们它是什么:类型,变量,函数,常量,宏等。 命名规则可以是任意的,但是一致性很重要,必须遵循规则。

一般命名原则


  • 使用甚至其他团队成员也可以理解的名称。
  • 名称应说明对象的目的或适用性。
  • 不要节省名称的长度,最好使用更长且更易理解的名称(即使是初学者)。
  • 缩写少,尤其是在项目外部不熟悉时。
  • 仅使用已知的缩写(Wikipedia知道吗?)。
  • 不要缩短单词。

通常,名称的长度应与范围的大小匹配。 例如, n是5行函数内的一个合适的名称,但是,当描述一个类时,这可能有点短。

class MyClass { public: int CountFooErrors(const std::vector<Foo>& foos) { int n = 0; //       for (const auto& foo : foos) { ... ++n; } return n; } void DoSomethingImportant() { std::string fqdn = ...; //      } private: const int kMaxAllowedConnections = ...; //     }; 

 class MyClass { public: int CountFooErrors(const std::vector<Foo>& foos) { int total_number_of_foo_errors = 0; //       for (int foo_index = 0; foo_index < foos.size(); ++foo_index) { //   `i` ... ++total_number_of_foo_errors; } return total_number_of_foo_errors; } void DoSomethingImportant() { int cstmr_id = ...; //   ( ) } private: const int kNum = ...; //       }; 

请注意,典型名称也有效: i表示迭代器或计数器, T表示模板参数。

将来,在描述规则时,“单词” /“单词”是所有用英文写的,没有空格,包括缩写。 总之,第一个字母可以大写(取决于样式:“ 驼峰大小写 ”或“帕斯卡大小写”),其余字母为小写。 例如,最好是StartRpc()最好是StartRPC()

模板参数还遵循其类别的规则:类型名称,变量名称等...

档案名称


文件名只能用小写字母书写,您可以使用下划线( _ )或连字符( - )分隔它们。 使用项目中使用的分隔符。 如果没有单一方法,请使用“ _”。

合适名称的示例:

  • my_useful_class.cc
  • 我有用的类
  • myusefulclass.cc
  • myusefulclass_test.cc //不推荐使用_unittest和_regtest。

C ++文件应以.cc结尾,标头应位于
.h 。 包含为文本的文件必须以.inc结尾(另请参见独立标题一节)。

不要使用/ usr / include中已经存在的名称,例如db.h。

尝试给文件指定特定名称。 例如, http_server_logs.h优于logs.h。 成对使用文件时,最好给它们起相同的名称。 例如, foo_bar.hfoo_bar.cc (并包含类FooBar )。

类型名称


类型名称以大写字母开头,每个新单词也以大写字母开头。 不使用下划线MyExcitingClassMyExcitingEnum

所有类型的名称(类,结构,别名,枚举,模板参数)均以相同的样式命名。 类型名称以大写字母开头,每个新单词也以大写字母开头。 不使用下划线。 例如:

 // classes and structs class UrlTable { ... class UrlTableTester { ... struct UrlTableProperties { ... // typedefs typedef hash_map<UrlTableProperties *, std::string> PropertiesMap; // using aliases using PropertiesMap = hash_map<UrlTableProperties *, std::string>; // enums enum UrlTableErrors { ... 

变量名


变量(包括函数参数)和数据成员的名称以小写字母表示,单词之间带有下划线。 这些类(不是结构)的成员在名称的末尾加上下划线。 例如: a_local_variablea_struct_data_membera_class_data_member_

通用变量名


例如:

 std::string table_name; // OK -     

 std::string tableName; //  -   

类数据成员


这些类的成员(静态和非静态)被称为普通变量,并在末尾添加下划线。

 class TableInfo { ... private: std::string table_name_; // OK -    static Pool<TableInfo>* pool_; // OK. }; 

结构数据成员


结构数据的成员(静态和非静态)称为常规变量。 最后没有添加下划线。

 struct UrlTableProperties { std::string name; int num_entries; static Pool<UrlTableProperties>* pool; }; 

另请参见“ 结构与类” ,它描述了何时使用结构,何时使用类。

常数名称


对象被声明为constexpr或const,因此该值在执行期间不会更改。 常数的名称以符号“ k”开头,然后以混合样式(大小写字母)出现。 在大写字母不能用于分隔的极少数情况下,可以使用下划线。 例如:

 const int kDaysInAWeek = 7; const int kAndroid8_0_0 = 24; // Android 8.0.0 

所有具有静态存储类型(即静态或全局,在此处有更多详细信息: 存储持续时间 )的相似常量对象也会被命名。 对于其他类型的存储中的变量(例如,自动常量对象),此约定是可选的。

功能名称


常用功能以混合样式(大写和小写字母)命名; 变量访问函数(访问器和增变器)应具有与目标变量相似的样式。

通常,函数名称以大写字母开头,并且名称中的每个单词都大写。

 void AddTableEntry(); void DeleteUrl(); void OpenFileOrDie(); 

(类似的规则适用于属于API的类或名称空间区域中的常量,并且应该看起来像函数(并且它们不是函数的事实并不重要))

访问器和修改器(获取和设置函数)的命名方式可以与相应的变量类似。 它们通常对应于实际成员变量,但这不是必需的。 例如, int count()void set_count(int count)

命名空间命名空间


命名空间称为小写。 顶级名称空间基于项目的名称。 避免名称与其他知名名称空间冲突。

顶级名称空间通常是项目或团队(由其编写代码)的名称。 该代码应位于名称对应于名称空间的目录(或子目录)中。

不要忘记不要使用缩写的规则-这也适用于名称空间。 内部代码不太可能需要名称空间引用,因此缩写是多余的。

避免将已知名称用于嵌套名称空间。 名称之间的冲突可能会导致在组装过程中出现意外。 特别是,请勿创建名为std的嵌套名称空间。 建议使用唯一的项目标识符( websearch :: indexwebsearch :: index_util ),而不是不防冲突的websearch :: util

对于内部/内部名称空间,添加其他代码时可能会发生冲突(内部帮助程序倾向于在不同的团队中重复)。 在这种情况下,使用文件名命名空间很有帮助。 ( websearch :: index :: frobber_internalfrobber.h中使用)

枚举名称


枚举(既有范围约束又无范围)必须称为常量 。 即: kEnumNameENUM_NAME

最好将枚举器中的各个值命名为常量。 但是,可以将其称为宏。 UrlTableErrors (和AlternateUrlTableErrors )枚举本身的名称是一种类型。 因此,使用了混合样式。

 enum UrlTableErrors { kOk = 0, kErrorOutOfMemory, kErrorMalformedInput, }; enum AlternateUrlTableErrors { OK = 0, OUT_OF_MEMORY = 1, MALFORMED_INPUT = 2, }; 

在2009年1月之前,枚举值的命名方式类似于宏。 这就产生了重复的宏名称和枚举值的问题。 应用常量样式可以解决此问题,最好在新代码中使用常量样式。 但是,无需重写旧代码(只要没有重复问题)。

宏名称


您不打算定义宏吗? 以防万一(如果要去),它们应该看起来像这样:
MY_MACRO_THAT_SCARES_SMALL_CHILDREN_AND_ADULTS_ALIKE

请阅读如何定义宏 ; 通常,不应使用宏。 但是,如果您绝对需要它们,请用大写字母加上下划线命名。

 #define ROUND(x) ... #define PI_ROUNDED 3.0 

命名异常


如果需要命名在现有C或C ++代码中具有类似物的名称,请遵循代码中使用的样式。

bigopen()
函数名称源自open()

int
定义类似于标准类型

大波斯
pos派生的结构

sparse_hash_map
类STL实体; 遵循STL风格

LONGLONG_MAX
INT_MAX这样的常量

注意:链接可能会导致手册中尚未翻译的部分。

Source: https://habr.com/ru/post/zh-CN477722/


All Articles