标签:
6 命名约定 Naming
最重要的一致性规则是命名管理govern naming; 命名风格快速获取名字代表是什么: 类型? 变量, 函数, 常量, 宏, ...甚至不需要去查找类型声明; 大脑中的模式匹配引擎pattern-matching engine可以非常可靠的处理这些命名规则;
命名规则具有一定随意性, 但相比按个人喜好命名, 一致性更重要, 所以不管你怎么想, 规则总归是规则;
6.1 通用命名规则 General Naming Rules
Tip 函数命名, 变量命名, 文件命名应局部描述性descriptive; 不要过度缩写; 类型和变量应该是名词, 函数名可以用"命令性"动词;
尽可能给出描述性的名称; 不要花心思去节省行空间, 让你的代码立刻能被理解要重要得多; 不要使用容易引起歧义的缩写, 或者对项目外的读者陌生的缩写, 不要简单地删除几个字符来做出一个简写名称;
1
2
|
int num_errors; //
Good. "num" is a widespread convention. int num_completed_connections; //
Good. |
糟糕的命名使用含糊的缩写或随意的字符:
1
2
3
|
int n; //
Bad - meaningless. int nerr; //
Bad - ambiguous abbreviation. int n_comp_conns; //
Bad - ambiguous abbreviation. |
类型和变量名一般为名词: 如 FileOpener, num_errors;
函数名通常是指令性的(确切的说它们应该是命令), 如 OpenFile(), set_num_errors(); 取值函数是个特例(在函数命名处详细阐述), 函数名和它要取值的变量同名;
缩写:
除非该缩写在其他地方都非常普遍, 否则不要使用; 例如:
1
2
3
4
|
// Good // These show proper names with no abbreviations. int num_dns_connections; //
大部分人都知道 "DNS" 是啥意思. int price_count_reader; //
OK, price count. No abbreviation |
WARNING
1
2
3
4
5
|
// Bad! // Abbreviations can be confusing or ambiguous
outside a small group. int wgc_connections; //
Only your group knows what this stands for. int pc_reader; //
Lots of things can be abbreviated "pc". int cstmr_id; //
Deletes internal letters. |
永远不要用省略字母的缩写:
1
2
|
int error_count; //
Good. int error_cnt; //
Bad. |
6.2 文件命名 File Names
Tip: 文件名要全部小写, 可以包含下划线 _ 或连字符 - , 按项目约定来; 如果原本没有一致的规律, 建议用 "_";
可接受的文件命名:
1
2
3
4
|
my_useful_class.cc my-useful- class .cc myusefulclass.cc myusefulclass_test.cc //
_unittest and _regtest are deprecated. |
C++文件要以 .cc结尾, 头文件以 .h结尾;
[Add] 需要以文本textually形式包含到特定位置的文件应该以 .inc结尾; 参考self-contained headers <<
不要使用已经存在于 /usr/include下的文件名; (译注: 即编译器搜索系统头文件的路径), 如 db.h;
通常应尽量让文件名更加明确; http_server_logs.h就比 logs.h要好; 定义类时文件名一般成对出现, 如 foo_bar.h和 foo_bar.cc, 对应于类 FooBar;
内联函数必须放在 .h文件中; 如果内联函数比较短, 就直接放在 .h中; 如果代码比较长, 可以放到以 -inl.h 结尾的文件中; 对于包含大量内联代码的类, 可以使用三个文件:
1
2
3
|
url_table.h //
The class declaration. url_table.cc //
The class definition. url_table-inl.h //
Inline functions that include lots of code. |
参考 -inl.h文件一节;
6.3 类型命名 Type Names
Tip 类型名称的每个单词首字母均大写, 不包含下划线underscore: MyExcitingClass, MyExictingEnum;
所有类型命名 -- 类, 结构体, 类型定义(typedef), 枚举--均使用相同约定convention; [Add] 类型名字应该由一个大写字母开始, 每个新单词都以大写字母开头, 没有下划线<<<例如:
1
2
3
4
5
6
7
8
9
10
|
// classes and structs class UrlTable
{ ... class UrlTableTester
{ ... struct UrlTableProperties
{ ... // typedefs typedef hash_map<UrlTableProperties
*, string> PropertiesMap; // enums enum UrlTableErrors
{ .. |
6.4 变量命名 Variable Names
Tip 变量名一律小写, 单词之间用下划线连接; 类(而非结构体)的成员变量以下划线结尾trailing underscore; 如:
[Add] a_local_variable, a_struct_data_member, a_class_data_member_ <<<
1
2
|
my_exciting_local_variable my_exciting_member_variable_ |
普通变量命名 Common Variable names
举例: [下划线会让名字更长, 全小写会有混淆出现: foot+ball -> football 类似]
1
2
|
string table_name; //
OK - uses underscore. string tablename; //
OK - all lowercase. |
WARNING: [why?打字麻烦?]
1
|
string tableName; //
Bad - mixed case. |
[Add]
类数据成员 Class Data Members
对于类数据成员, static和non-static的, 都和普通非成员变量一样命名, 但是以下划线结尾;
1
2
3
4
5
6
7
|
class TableInfo
{ ... private : string
table_name_; //
OK - underscore at end. string
tablename_; //
OK. static Pool<TableInfo>*
pool_; //
OK. }; |
<<<
结构体变量 Struct Data Members
结构体的数据成员, static和non-static的, 可以和普通变量一样, 不用像类那样接下划线:
1
2
3
4
5
|
struct UrlTableProperties
{ string
name; int num_entries; static Pool<UrlTableProperties>*
pool; }; |
结构体与类的讨论参考 Structs vs. Classes
全局变量 Global Variables
对全局变量没有特别要求, 少用就好, 但如果你要用, 可以用 g_ 或其他标志作为前缀, 以便更好地区分局部变量;
6.5 常量命名 Constant Names
Tip 在名称前加 k: kDaysInAWeek; 混合大小写, 对于在全局或类内定义的常量;
为方便阅读, 所有编译时常量, 无论是局部的, 全局的还是类中的, 和其他变量稍微区别一下; k后接大写字母开头的单词:
1
|
const int kDaysInAWeek
= 7; |
[Add] 这个约定对于local范围的编译时常量来说不是强制的, 那种情况下用一般命名规则也可以;<<<
6.6 函数命名
Tip 常规函数使用大小写混合, 取值和设置函数则要求与变量名匹配:
MyExcitingFunction(), MyExcitingMethod(), my_exciting_member_variable(), set_my_exciting_member_variable();
常规函数 Regular Functions
函数名的每个单词首字母大写, 没有下划线:
1
2
|
AddTableEntry(); DeleteUrl(); |
[Add] 如果函数会在一个error上崩溃crash, 你应该加上OrDiie, 这只适用于会在产品代码中使用, 而且error是在一般操作下合理发生的情况下;
1
|
OpenFileOrDie() |
取值和设值函数 Accessors and Mutators
取值和设值函数((get and set)要与存取的变量名匹配; 这儿摘录一个类, num_entries_ 是该类的实例变量;
1
2
3
4
5
6
7
8
9
|
class MyClass
{ public : //... int num_entries() const { return num_entries_;
} void set_num_entries( int num_entries)
{ num_entries_ = num_entries; } private : int num_entries_; }; |
其他非常短小的内联函数名也可以用小写字母, 例如: 如果你在循环中调用这样的函数甚至都不用缓存其返回值, 小写命名就可以接受;
6.7 名字空间命名 Namespace Names
Tip 名字空间用小写字母命名, 并给予项目名称和目录结构: google_awesome_project; [小写是为了和类区分?]
关于名字空间的讨论和如何命名, 参考Namespaces;
6.8 枚举命名 Enumerator Names
Tip 枚举的命名应当和 常量 或 宏 一致: kEnumName或是 ENUM_NAME;
单独的枚举值应该优先采用常量的命名方式; 但宏方式的命名也可以接受; 枚举名 UrlTableErrors(或AlternateUrlTableErrors)是类型; 所以要用大小写混合的方式;
1
2
3
4
5
6
7
8
9
10
|
enum UrlTableErrors
{ kOK
= 0, kErrorOutOfMemory, kErrorMalformedInput, }; enum AlternateUrlTableErrors
{ OK
= 0, OUT_OF_MEMORY
= 1, MALFORMED_INPUT
= 2, }; |
2009 Jan之前我们一直建议采用宏的方式命名枚举值; 由于枚举值和宏之间的命名冲突collision, 直接导致了很多问题; 因此, 这里改为优先选择常量风格constant-style的命名方式; 新代码应该尽可能优先使用常量风格; 但老代码没必要切换到常量风格, 除非宏风格确实会产生编译期问题;
6.9 宏命名 Macro Names
Tip 你并不打算使用宏吧? 如果一定要用, 像这样命名: MY_MACRO_THAT_SCARES_SMALL_CHILDREN
参考 预处理宏description of macros, 通常不应该使用宏; 如果不得不用, 其命名像枚举命名一样全部大写, 使用下划线;
1
2
|
#define ROUND(x) ... #define PI_ROUNDED 3.0 |
6.10 命名规则的特例 Exceptions to Naming Rules
Tip 如果你命名的实体已有 C/C++实体相似analogous, 可参考现有命名策略convention scheme;
bigopen(): 函数名, 参照 open()的形式;
unit: typedef
bigpos: struct或 class, 参照 pos的形式;
sparse_hash_map: STL相似实体, 参照STL命名约定;
LONGLONG_MAX: 常量, 如同 INT_MAX;
---TBC---YCR
标签:
原文地址:http://blog.csdn.net/roymuste/article/details/43969827