目录
命名规则的例外情况(Exceptions to Naming Rules)
管理命名是最重要的保持一致性的规则。通过名称的风格,我们不用看其声明就可以立即猜出命名实体是什么:一个类型、一个变量、一个函数、一个常量或者一个宏等。我们大脑的模式匹配机制在处理识别这些命名规则时起了很大的作用。
命名规则非常随意,但我们觉得在编程领域,一致性比个人表现更为重要,所以,无论是否合理,规则就是规则。
一般命名规则(General Naming Rules)
函数名称、变量名称和文件名称应该具有描述性并且避免简写。类型名和变量名应该是名称,而函数名则应该是命令动词。
怎样命名(How to Name)
在合理的情况下,尽量给出描述性的命名。不要考虑⽔水平空间,毕竟让你的代码能立即被新读者明白要重要得多。比较好的命名:
int num_erros; // 很好
int num_completed_connections; // 很好
而下面的命名则很不好,要么使用不明确的缩写、要么用无法传达意义的任意字符:
int n; // 不好-⽆无法表达变量意义
int nerr; // 不好-不明确的缩写
int n_comp_conns; // 不好-不明确的缩写
类型名和变量名通常应该是名词,比如FileOpener_num_errors。
函数名通常应该具有祈使性( 也就是说它们应该是命令) , 比如OpenFile(),set_num_errors()。访问器是一个例,它应该基于其访问的成员来命名,这一点在函数命名中有详细描述。
缩写(Abbreviations)
不要使用缩写,除非这些缩写在项目外被广泛接受。比如:
//很好-这些名称没有缩写
int num_dns_connections; // ⼤大多数⼈人知道DNS代表什么
int price_count_reader; // 很好-价格计数。名称有意义
不要以省略字符的方式缩写:
int error_count; // 很好
int error_cnt; // 糟糕
文件命名(File Names)
文件名应该全部小写,可以含有下划线(_)和连字符(-)。对于连接符号(_或-)的选择,可以遵照项目的约定,如果没有统一要求,最好选择下划线(_)。
好文件名⽰示例:
my_useful_class.cc
my-useful-class.cc
myusefulclass.cc
myusefulclass_test.cc //不再使⽤用_unittest和_regtest
C++源文件应该以.cc作为扩展名而头文件则以.h作为扩展名。
不要与/usr/include中的文件重名,比如db.h。通常,应该使你的文件名尽量具体。比如用http_server_logs.h就比logs.h好得多。一种很常见的情况是一对文件foo_bar.h和foo_bar.cc定义一个叫作FooBar的类。
内联函数必须在头文件中定义。如果头文件很短,可以直接放在头文件中。然而,如果内联函数包含很多代码,它们应该在第三个以-inl.h结尾的文件中定义。如果类有很多内联代码,你的类应该有3个文件:
url_table.h // 类声明
url_table.cc // 类定义
url_table_inl.h // 包括⼤大量代码的内联函数
另外,参见内联头文件(-inl.h Files)。
类型命名(Type Names)
类型名以大写字母开头,每个单词的⾸首字母大写,中间没有下划线。所有类型——类、结构体、类型定义(typedef)和枚举——都符合统一的命名约定。比如
// 类和结构体
class UrlTable{...
class UrlTableTeser{...
struct UrlTableProperties{...
变量命名(Variable Names)
变量名所有字母小写,单词之间用下划线(_)分开,类成员变量以下划线结束。
普通变量命名(Common Variable Names)
比如:
string table_name; // 可以-使⽤用下划线
string tablename; // 可以-全部字母小写
string tableName; // 糟糕-大小写混合
类数据组成变量命名(Class Data Members)
数据成员(又叫实例变量或者成员变量)的命名与普通变量一样,全部字母小写,可选的下划线分隔符,但应该以下划线结束。
string table_name_; // 可以-以下划线结束
string tablename_; // 可以
结构体成员变量命名(Struct Variables)
结构体成员变量和普通变量命名规则一致,且不像类成员变量以下划线结束。
struct UrlTableProperties{
string name;
int num_entries;
}
参见结构体与类部分的关于它们使用的讨论。
全局变量命名(Global Variables)
全局变量的使用较为罕见,但当用到时,考虑以前缀g_开头或标以其他记号,以便局部变量区分。
常量命名(Constant Names)
K后跟混合大小写的名称:kDaysInAWeek。所有编译时常量,不管是被声明为局部、全局还是作为类的成员,都应该遵守与其他变量命名有轻微差别的命名约定:k后跟单词⾸首字母大写的名称:
const int kDaysInAWeek = 7;
函数命名(Function Names):
正规函数有很多复杂情况: 访问器和修改器以变量名命名: MyExcitingFunction(),MyExcitingMethod(),my_exciting_member_variable(),set_my_exciting_member_variable()。
正规函数命名(Regular Functions)
正规函数名应该以大写字母开头,单词⾸首字母大写,不使用下划线。如果函数可能因错误而崩溃,应该在函数名后加上OrDie。这仅适用于那些被产品代码调用或者正常操作有可能引起错误的函数。
AddTableEntry()
DeleteUrl()
访问器和修改器(Accessors and Mutators)
访问器和修改器(get和set函数)应该与它们关联的变量名匹配。下面显⽰示了一个类的部分摘录,它有一个实例变量num_entries
class MyClass{
public:
void set_num_entries(int num_entries)
{
num_entries_ = num_entries;
}
int get_num_entries(int num_entries)
{
return num_entries_;
}
private:
int num_entries_;
};
你也可以使用小写字母和下划线来命名非常短小的内联函数。比如,如果一个函数的调用开销很小,在循环调用时,没必要缓存其值,这时,小写字母命名是允许的。
名称空间的命名(Namespace Names)
名称空间以小写字母命名, 名称基于项目名称和项目的目录结构:google_awesome_project。
参见名称空间部分关于名称空间及其命名的讨论。
枚举器的命名(Enumerator Names)
枚举器要么像常量一样,要么像宏一样命名:或者kEnumName,或者ENUM_NAME。通常,枚举变量按常量命名方式命名更好。然而,按宏命名方式亦未尝不可。下面的例子中,枚举的命名是一个类型,因此是一个混合情况:
enum UrlTableErros{
kOK = 0;
直到2009年1⽉月,枚举的命名方式都依据宏。这在枚举和宏之间引起了名称冲突。因此才将其改为常量命名方式。新代码应该遵照这一约定。然而,旧代码没必要修改,除非这会引起编译时问题。
宏命名(Macro Names)
你真的打算定义宏吗? 如果的确如此, 这样命名:MY_MACRO_THAT_SCARES_SMALL_CHILDREN。参见宏描述(Description of macros)。
#define ROUND(x) ...
#define PI_ROUNDED 3.0
命名规则的例外情况(Exceptions to Naming Rules)
如果你给与已有C或C++实体相似的实体命名,可以遵照已有命名约定模式。
- bigopen() 函数名称,继承自open()
- uint 类型定义
- bigpos 结构体或类,根据pos
- sparse_hash_map 类标准模板库实体,根据STL命名约定
- LONGLONG_MAX 一uc2 .常量,类似INT_MAX