GoogleCStyleGuide谷歌C编码风格指南.docx
《GoogleCStyleGuide谷歌C编码风格指南.docx》由会员分享,可在线阅读,更多相关《GoogleCStyleGuide谷歌C编码风格指南.docx(45页珍藏版)》请在得力文库 - 分享文档赚钱的网站上搜索。
1、谷歌C+编程风格指南版本:3.180Benjy WeinbergerCraig SilversteinGregory EitzmannMark MentovaiTashana Landray翻译:郑州大学赵峻(仅供参考)目录、背景 1二、正文11. 头文件(Header Fi les)11.1 1 #def ine 保护(#include guard)11.2 头文件的依赖关系(Header File Dependencies)21.3 内联函数(Inline Functions)21.4 内联头文件(The - inl.h Files)31.5 5函数参数次序(Function Parame
2、ter Order ing)31.6 包含的命名和次序(Names and Order of i nc I udes)32. 作用域(Scop ing) 42. 1 名称空间(Namespaces)43. 2 类嵌套(Nested Classes)74. 3外部函数、静态成员函数和全局函数(Nonmember, Static Member, andGIobaI Functions)75. 4局部变量(Local Variables)86. 5静态变量和全局变量(Stat ic and Global Var iables)83. 类 (Classes)93. I在构造函数中完成工作(Doing
3、Work in Constructors)94. 2默认构造函数(Default Constructor)95. 3显式构造函数(Expl icit Constructors)106. 4复制构造函数(Copy Constructos)107. 5结构体与类(Structs vs Classes)118. 6继承(Inher i tance)119. 7多重继承(Mu It ip Ie Inher i tance)1210. 接口(Interface)1211. 9运算符重载(Operator Over loading)1212. 10访问控制(Access Control)1313. 11声
4、明次序(Dec larat ion Order)1314. 12定义简短函数(Write Short Functions)144. 谷歌经验技巧(Google-Specific Magic) 144 . 1 智能指针 (Smart Pointers) 145 .2 CPPI int145, 其他 C+特性(Other C+ Fetures) 155. 1弓I用参数 (Reference Arguments) 156. 2函数重载(Function Overloading)157. 3默认参数(Default Arguments)168. 4可变长度数组和内存申请(Var iable-Lengt
5、h Arrays and a I I oca () 165 5(i r I ends)169. 6异常处理(Excpet i ons)1710. 7运行时类型信息(Run-Time Type Information, RTTI)1811. 8类型转换(Cast ing)1812. 9流(Streams)1813. 10 前置自增和前置自减(Preincrement and Predecrement)2014. 11const 修饰符的使用(Use of const)2015. 12 整型类型(Integer Types)2116. 1364 位兼容性(64-bit Portabi I ity)
6、2117. 14 预处理宏(Preprocessor Macros)2218. 15 和空(0 and NULL)2319. 16 存储容量运算符(sizeof)2320. 17 增强库(Boost)2321. 18C+ Ox 库2422. 命名(Naming)2423. 1一般命名规则(General Naming Rules)2424. 2 F F 卩 (l I I e Names) 2525. 3类型命名(Type Names)2626. 4变量命名(Var iable Names)2627. 5常重命名(Constant Names)2628. 6函数命名(Funct i on Nam
7、es) : 2729. 7名称空间的命名(Namespace Names)2730. 8枚举器的命名(Enumerator Names)2731. 9命名(Macro Names)2832. 10 命名规则的例外情况(Exceptions to Naming Rules)287B 注释(Comments)2833. 1注释风格(Comment Sty I e)2834. 2 文件注释(Fi Ie Comments)2835. 3类注释(Class Comments)2936. 4函数注释(Function Comments)2937. 5变量注释(Var iable Comments)3038
8、. 以空、真/假、数字作为参数(NULL、true/false、1,2, 3)3139. 7注释的标点、拼写和语法(Punctuation, Spel I ing and Gramma)3140. 8 TODO 注释(TODO Comments)3141. 9废弃性注释(Deprecation Comments)3242. 编码格式(Formatt ing)328. 1行长度(Line Length)328. 2非 ASCI I 码字符(Non-ASCI I Characters)338. 3窗格还是制表符(Spaces vs. Tabs)338. 4函数声明与定义(Function Decl
9、arations and Definitions)338. 5函数调用(Function Calls)348. 6条件语句(ConditonaIs)348. 7循环和多分支语句(Loops and Switch Statements)358. 8指针与引用表达式(Pointer and Reference Expressions)368. 9布刁表达式(Boolean Expressions)368. 10返回值(Return Va I ues)378. 11变量和数组的初始化(Variable and ArrayInitialization)378. 12预处理指令(Preprocessor
10、 Directives)378. 13类格式(Class Format)378. 14构造函数初始化列表(Constructor Initial izerLists)388. 15 名称空间格式(Namespace Formatting)388. 16水平空白(Hor izontaI Whitespace)388. 17垂直空白(Vertical Whitespace)409. 本规则的例外情况(Exceptons to the Rules)409. 1 现存不一致代码(Existing Non-conformantCode)4010. 2 Windows 代百马(Windows Code)4
11、011. 结束语(Parting Words)41、 冃景C+是很多谷歌开源项目的主开发语言。正如每一个C+程序员所知,C+拥有很多强 大的特性,但与此同时带也来了很大的复杂性,这就导致C+代码极易出现问题且很难阅读 和维护。本指南的目标就是根据大量经验,描述C+编码过程中建议和不提倡的编码规则,以便 控制其复杂性。这些规则的运用使你在高效而创造性地使用C+的同时,又能很好是保持代 码的可维护性。风格,或者说可读性,也就是我们C+编码的惯例。使用“风格”似乎有些用词不当, 毕竟惯例远远不止源文件的格式。保持代码可维护性的种方法就是强调编码的一致性。程序员能快速查看并理解其他程 序员的代码是很重
12、要的。维持种统风格并遵照惯例意味着我们可以简单地使用模式匹 配”来推断大量符号的含义和其不变性。建立通用、惯例和模式使代码更容易理解。也许有 时有必要改变我们的贯风格,尽管如此,我们还是尽量保持致性的好。本指南的另个论点是C+特性臃肿。C+是门包含有大量高级特性的巨型语言。某 些情况下,我们限制甚至禁止使用某些特性。我们这样做仅仅是想使代码简单并避免由这些 特性引起的大量常见错误和问题。本指南将列出这些特性并指出为什么限制它们的使用。谷歌所有开源项口都符合本指南中的要求。注意:本指南不是C+入门指导,我们假设读者对C+已经非常熟悉。二、正文1 .头文件(Header Fi les)通常,每个源
13、文件(.ccfile)文件都应该有一个与之关联的头文件(.hfile)文件。 当然,有一些常见例外,比如只有一个main ()函数的单元测试和小源文件。正确地使用头文件可以使代码的可读性、体积和性能有一个大的提升。通过下面的规则,你将了解大量使用头文件的缺陷。1. 1#define 保护(#include guard)每个头文件都应该有一个#define保护以防止它被多次包含。而且符号的命名最好是 以下形式:_H_尽管保护各不相同,但它们应该以完整的项目资源目录为基础。比如foo项目中的 foo/src/bar/baz.h文件应该这样保护:#ifndef FOO_BAR_BAZ_H_defin
14、e FOO_BAR_BAZ_H一#endif / FOO_BAR_BAZ_H_1.2头文件的依赖关系(Header File Dependenc i es)当个前置声明足够时,不要使用#include。当你包含个头文件时,便引入了头文件依赖关系,每当这个头文件改变时,代码都需 要重新编译。而且,如果这些头文件还包含其他头文件,任何改变都将导致包含该头文件的 代码重新编译。因此,我们提倡最小化包含,尤其是头文件包含头文件的情形。你可以通过使用前置声明来明显地减少自定义头文件包含其他头文件的数量。比如,如 果你的头文件使用日ie类而不需要知道FUe类的声明,就可以前置声明File类,而不需要使 用
15、#include file/base/file . h,z如何在不访问其定义的情况下使用类Foo呢?1 .声明数据成员Foo或者Foo&;2 .声明以Fo。为参数,和/或返回值的函数。(有一个例外:如果参数是Fo。或者const Foo&,有一个隐式单参数构造函数,这种情况下我们需要引入完全定义来支持自动类 型转换)。3 .声明静态的F。数据成员,这是因为静态数据成员在类定义外定义。另一方面,如果你的类是F。的子类或者包括个F。类型的数据成员,你必须包含 该头文件。有时使用指针成员(或使用更好的智能指针)代替对象成员更合理。然而,这会使代码 的可读性复杂化并影响性能,所以,当仅以最小化包含文件
16、数为目的时,尽量不要这么做。通常,.cc文件需要知道其所用类的具体实现,因此需要包含些头文件。注意:如果你在cc文件中使用Foo标识符,你应该自己定义Foo,要么通过个 #include命令,要么通过个前置声明。然而有一个例外:如果在myf ile .cc中使用 Foo在myf ile.h中#include(或者前置声明)Foo也可以。1.3 内联函数(Inline Functions)当函数很小(比如10行或者更少)时定义函数为内联。内联定义:通过内联,编译器会在调用处将函数展开为代码,而不通过通常的函数调用 机制。利:由于内联函数通常很小,所以可产生更高效的目标代码。尽量内联类成员访问和修
17、 改函数(getters and setter)和其他些简短,对性能要求关键的函数。弊:过量使用内联将使程序性能受损。视其规模,内联个函数即可能使其代码量增加, 也可能使其代码量减少。内联个小的类成员访问函数(getter)通常会减小其代码量, 然而内联一个很大的函数则会显著增加其代码量。现代处理器由于使用了指令缓存,在运行 小规模代码时将更快。结论:个好的经验法则是,当个函数超过10行时,不要使用内联。注意析构函数,它们 常常因不明显的成员或者基类析构调用比看起来的规模大。另个有用的经验法则是,内联个包含有循环或者开关指令的函数常常是不划算的 (除非在极特殊情况会执行这些循环和开关指令)。知
18、道这一点很重要:些函数常常不能被内联,即使被声明成这样,比如虚函数和递归 函数常常不能被内联。内联个虚函数的主要原因是将它们的定义放在类定义中,或者在类 定义中说明它们的行为,比如类成员访问器和修改器。1.4 内联头文件(The - i n I. h Fil es)如有必要,你可以使用-ini前缀来定义复杂的内联函数。应该在头文件中定义内联函数,这样,编译器才能将其代码复制到调用处。然而,实现 代码通常应该包含在cc文件:头文件一般不包含实现代码,除非为了改善可读性或者出于 性能的考虑。如果一个内联函数的定义很短,包含很少(如果有的话)的逻辑判断,则应在头文件中 实现它们。比如,类成员访问器和
19、修改器应该在类定义中实现。为方便定义和调用,些复 杂的内联函数也可在头文件中定义,当这些函数使头文件变得太过臃肿时,增加一个 ini.h文件来单独定义它们。ini.h头文件使内联函数的实现和类的定义分开,同时又 允许在需要的时候包含其实现。-inl.h的另一个用途是定义函数模板。这将使你的函数模板定义可读性更好。另外,不要忘了,-ini .h文件也是需要#def ine保护的。1.5 函数参数次序(Function Parameter Ordering)当定义个函数时,其参数次序应该是:输入、输出。个C/C+函数的参数无外乎输入、输出或者兼具两者。输入参数常常是数值或者常引 用,而输出或者出入
20、参数则是非const指针。定义参数次序时,通常将所有输入参数置于 输出参数之前。尤其注意,不要简单在把新参数加在参数列表最后,要将新输入参数置于所 有输出参数之前。然而,这不是个一成不变的规则,比如出入参数(一般是类或结构体)。1.6 包含的命名和次序(Names and Order of i nc I udes)为增加可读性并避免隐蔽的依赖关系,请使用标准的包含次序:c库、C+库、其他库 头文件、自定义头文件。所有项目的头文件应该按其资源目录降序排列,且不要使用Unix的简略目录表示法(. 表示当前目录,.表示父目录)。比如, google-awesome-project/src/base/
21、logging.h 丿该区样被自含: include base/logging.h/z如果dir/foo.cc的主要功能是实现和测试dir2/foo2.h中的内容,可以这样安排:1. dir2/foo2. h2. C系统文件3. C+系统文件4. 其他库头文件5. 本项目头文件这种首选次序可以减少隐蔽的依赖关系。我们希望每个头文件都可以独立编译。最简 单的方法就是确保它们在.CC文件中是第一次被包含。dir/foo. cc 和 dir2/foo2 .h 通常在个目录中(比如 base/hasictypes_test. cc base/basictypes .h)当然,也可以在不同目录中。各部分
22、内,最好按字母表顺序排列。比如 google-awesome-project/src/f00/internal/fooserver.cc 可以以祥 排序包含文件:#include foo/public/fooserver,h”/首选位置include include include include include base/basictypes. hz, include base/commandlineflags . h include foo/public/bar.hz,2 .作用域(Scoping)3 . 1 名称空间(Namespaces)在.cc文件中,通常鼓励匿名名称空间。当需要命名
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- GoogleCStyleGuide 谷歌 编码 风格 指南
限制150内