1. 首页
  2. 数据库
  3. MongoDB
  4. Google C++编码规范中文版.pdf

Google C++编码规范中文版.pdf

上传者: 2020-11-25 12:35:47上传 PDF文件 776.14KB 热度 22次
背景 Google的项目大多使用C++开发。每一个C++程序员也都知道,C++具有很多强大的语言特性,但这 种强大不可避免的导致它的复杂,而复杂性会使得代码更容易出现bug、难于阅读和维护。 本指南的目的是通过详细闻述如何进行C++编码来规避其复杂性,使得代码在有效使用C++语言特性的 同时还易于管理。 使代码易于管理的方法之一是增强代码一致性,让别人可以读懂你的代码是很重要的,保持统-编程冈格 意味着可以轻松根据“模式匹配′′规则推断各种符号的含乂。创建通用的、必需旳习惯用语和模式可以使 代码更加容易理解在某些情况下改变-些编程风格可能会是好的选择但我们还是应该遵循一致性原则 尽量不这样去做。 本指南的另一个观点是C++特性的臃肿。C++是一门包含大量高级特性的巨型语言,某些情况下,我们会 限制甚至棽止使用某些特性使代码简化,避免可能导致的各种问题,指南中列举了这类特性,并解释说为 什么这些特性是被限制使用的 注意:本指南并非C++教程,我们假定读者已经对C++非常熟悉。 头文件 通常,每一个CC文件(C++的源文件)都有一个对应的h文件(头文件),也有一些例外,如单元测试代 码和只包含main的cc文件。 正确使用头文件可令代码在可读性、文件大小和性能上大为改观。 下面的规则将引导你规避使用头文件时的各种麻烦。 1.# define保护 所有头文件都应该使用# define防止头文件被多重包含( multiple inclusion),命名格式为 H 为保证唯一性,头文件的命名应基于其所在项目源代码树的全路径。例如,项目foo中的头文件 foo/src/bar/bazh按如下方式保护: #ifndef foo bar baz h #define FOo bar baz H #endif//FOO BAR BAZ H 2.头文件依赖 使用前置声明( forward declarations)尽量减少h文件中# include的数量 当一个头文件被包含的同时也引入了一项新的依赖( dependency),只要该头文件被修改,代码就要重新 编译。如果你的头文件包含了其他头文件,这些头文件的任何改变也将导致那些包含了你的头文件的代码 重新编译。因此,我们应该尽量少的包含头文件,尤其是那些包含在其他头文件中的 使用前置声明可以显著减少需要包含的头文件数量。举例说明:头文件中用到类Fle,但不需要访问File 的声明,则头文件中只需前置声明 class File无需# include"file/base/ieh"。 在头文件如何做到使用类Foo而无需访问类的定乂? 1)将数据成员类型声明为Foo*或Foo& 2)参数、返回值类型为Foo的函数只是声明(但不定义实现); 3)静态数摇成员的类型可以被声明为Foo,因为静态数据成员的定义在类定义之外 另一方面,如果你的类是Foo的子类,或者含有类型为Foo的非静态数据成员,则必须为之包含头文件 有时,使用指针成员( pointer members,如果是 scoped_ptr更好)替代对象成员( object members) 的确更有意义。然而,这样的做法会降低代码可读性及执行效率。如果仅仅为了少包含头文件,还是不要 这样替代的好。 当然,cc文件无论如何都需要所使用类的定义部分,自然也就会包含若干头文件。 注:能依赖声明的就不要依赖定义。 3.内联函数 只有当函数只有10行甚至更少时才会将其定义为内联函数( inline function b 定义( Definition):当函数被声明为内联函数之后,编译器可能会将其内联展开,无需按通常的凶数调用 机制调用内联函数。 优点:当函数体比较小的时候,內联该函数可以令目标代码更加高效。对于存取函数( accessor、 mutator) 以及其他一些比较短的关键执行函数。 缺点:滥用内联将导致程序变慢,内联有可能是目标代码量或増或减,这取决于被內联的函数的大小ν。内 联较短小的存取函数通常会减少代码量,但内联一个很大的函数(注:如果编译器允许的话)将显著增加 代码量。在现代处理器上,由于更好的利用指令缓存( instruction cache),小巧的代码往往执行更快。 结论:一个比较得当的处理规则是,不要內联超过10行的函数。对于析构凶数应慎重对待,析构函数往 往比其表面看起来要长,因为有一些隐式成员和基类析构函数(如果有的话)被调用! 另一有用的处理规则:內联那些包含循环或 switch语句的凶数是得不偿失的,除非在大多数情况下,这些 循环或 switch语句从不执行。 重要的是,虚函数和递归函数即使被声明为內联的也不一定就是內联函数。通常,递归函数不应该破声明 为内联的(译者注∶递归调用堆栈的展开并不像循环那么简单,比如递归层数在编译时可能是未知的,大 多数编译器都不支持內联递归函数)析构函数內联的主要原因是其定义在类的定义中,为了方使抑或是对 其行为给出文档 4.-inl.h文件 复杂的内联函数的定义,应放在后缀名为-nh的头文件中 在头文件中给出内联函数的定叉,可令编译器将其在调用处内联展开。然而,实现代码应完全放到,cc文件 中,我们不希望h文件中出现太多实现代码,除非这样做在可读性和效率上有明显优势。 如果內联函数的定义比较短小、逻辑比较简单,其实现代码可以放在h文件中。例如,存取函数的实现理 所当然都放在类定义中。出于实现和调用的方便,较复杂的内联函数也可以放到.h文件中,如果你觉得这 样会使头文件显得笨重,还可以将其分离到单独的-inl.h中。这样即把实现和类定义分离开来,当需要时 包含实现所在的-in!h即可。 -in!h文件还可用于函数模板的定义,从而使得模板定义可读性增强。 要提醒的一点是,-in.h和其他头文件一样,也需要# define保护。 5.函数参数顺序( Function Parameter Ordering) 定义函数时,参数顺序为:输入参数在前,输出参数在后。 C/C++函数参数分为输入参数和输出参数两种,有时输入参数也会输出(注:值被修改时输入参数一 般传值或常数引用( const references),输出参数或输入/输出参数为非常数指钆(non-
下载地址
用户评论