logo资料库

Google C++ 风格指南 - 中文版 Word整理.docx

第1页 / 共62页
第2页 / 共62页
第3页 / 共62页
第4页 / 共62页
第5页 / 共62页
第6页 / 共62页
第7页 / 共62页
第8页 / 共62页
资料共62页,剩余部分请下载后查看
Google C++ 风格指南 - 中文版
译者前言
背景
1. 头文件
1.1. #define 保护
1.2. 头文件依赖
1.3. 内联函数
1.4. -inl.h文件
1.5. 函数参数的顺序
1.6. #include 的路径及顺序
译者 (YuleFox) 笔记
2. 作用域
2.1. 名字空间
2.1.1. 匿名名字空间
2.1.2. 具名的名字空间
2.2. 嵌套类
2.3. 非成员函数, 静态成员函数, 和全局函数
2.4. 局部变量
2.5. 静态和全局变量
译者 (YuleFox) 笔记
3. 类
3.1. 构造函数的职责
3.2. 默认构造函数
3.3. 显式构造函数
3.4. 拷贝构造函数
3.5. 结构体 VS. 类
3.6. 继承
3.7. 多重继承
3.8. 接口
3.9. 运算符重载
3.10. 存取控制
3.11. 声明顺序
3.12. 编写简短函数
译者 (YuleFox) 笔记
4. 来自 Google 的奇技
4.1. 智能指针
4.2. cpplint
5. 其他 C++ 特性
5.1. 引用参数
5.2. 函数重载
5.3. 缺省参数
5.4. 变长数组和 alloca()
5.5. 友元
5.6. 异常
5.7. 运行时类型识别
5.8. 类型转换
5.9. 流
5.10. 前置自增和自减
5.11. const 的使用
5.12. 整型
5.13. 64 位下的可移植性
5.14. 预处理宏
5.15. 0 和 NULL
5.16. sizeof
5.17. Boost 库
6. 命名约定
6.1. 通用命名规则
6.2. 文件命名
6.3. 类型命名
6.4. 变量命名
6.5. 常量命名
6.6. 函数命名
6.7. 名字空间命名
6.8. 枚举命名
6.9. 宏命名
6.10. 命名规则的特例
7. 注释
7.1. 注释风格
7.2. 文件注释
7.3. 类注释
7.4. 函数注释
7.5. 变量注释
7.6. 实现注释
7.7. 标点, 拼写和语法
7.8. TODO 注释
译者 (YuleFox) 笔记
8. 格式
8.1. 行长度
8.2. 非 ASCII 字符
8.3. 空格还是制表位
8.4. 函数声明与定义
8.5. 函数调用
8.6. 条件语句
8.7. 循环和开关选择语句
8.8. 指针和引用表达式
8.9. 布尔表达式
8.10. 函数返回值
8.11. 变量及数组初始化
8.12. 预处理指令
8.13. 类格式
8.14. 初始化列表
8.15. 名字空间格式化
8.16. 水平留白
8.17. 垂直留白
译者 (YuleFox) 笔记
9. 规则特例
9.1. 现有不合规范的代码
9.2. Windows 代码
10. 结束语
Google C++ 风格指南 - 中文版¶ 版本: 3.133 Benjy Weinberger Craig Silverstein 原作者: Gregory Eitzmann Mark Mentovai Tashana Landray 翻译: YuleFox yospaly 项目主页:   Google Style Guide Google 开源项目风格指南 - 中文版 Arranged By Corsair
Google C++ 风格指南 - 中文版 1 目录 Google C++ 风格指南 - 中文版¶ .................................................1 译者前言¶ .................................................................... 1 背景¶ ........................................................................ 1 1. 头文件¶ ................................................................... 3 1.1. #define 保护¶ ....................................................... 3 1.2. 头文件依赖¶ ......................................................... 3 1.3. 内联函数¶ ........................................................... 3 1.4. -inl.h 文件¶ .........................................................4 1.5. 函数参数的顺序¶ ..................................................... 4 1.6. #include 的路径及顺序¶ .............................................. 5 译者 (YuleFox) 笔记¶ ..................................................... 5 2. 作用域¶ ................................................................... 7 2.1. 名字空间¶ ........................................................... 7 2.1.1. 匿名名字空间¶ ................................................. 7 2.1.2. 具名的名字空间¶ ............................................... 7 2.2. 嵌套类¶ ............................................................. 9 2.3. 非成员函数, 静态成员函数, 和全局函数¶ ............................... 9 2.4. 局部变量¶ .......................................................... 10 2.5. 静态和全局变量¶ .................................................... 10 译者 (YuleFox) 笔记¶ .................................................... 11 3. 类¶ ...................................................................... 12 3.1. 构造函数的职责¶ .................................................... 12 3.2. 默认构造函数¶ ...................................................... 12 3.3. 显式构造函数¶ ...................................................... 13 3.4. 拷贝构造函数¶ ...................................................... 13 3.5. 结构体 VS. 类¶ ..................................................... 15 3.6. 继承¶ .............................................................. 15 3.7. 多重继承¶ .......................................................... 17 3.8. 接口¶ .............................................................. 17 3.9. 运算符重载¶ ........................................................ 18 3.10. 存取控制¶ ......................................................... 18 3.11. 声明顺序¶ ......................................................... 19 3.12. 编写简短函数¶ ..................................................... 19 译者 (YuleFox) 笔记¶ .................................................... 19 4. 来自 Google 的奇技¶ ...................................................... 21 4.1. 智能指针¶ .......................................................... 21 4.2. cpplint¶ ........................................................... 21 5. 其他 C++ 特性¶ ........................................................... 22 5.1. 引用参数¶ .......................................................... 22 5.2. 函数重载¶ .......................................................... 22 5.3. 缺省参数¶ .......................................................... 23 5.4. 变长数组和 alloca()¶ ............................................... 23 5.5. 友元¶ .............................................................. 23 5.6. 异常¶ .............................................................. 24 5.7. 运行时类型识别¶ .................................................... 25 5.8. 类型转换¶ .......................................................... 25
Google C++ 风格指南 - 中文版 2 5.9. 流¶ ................................................................ 26 5.10. 前置自增和自减¶ ................................................... 27 5.11. const 的使用¶ ..................................................... 28 5.12. 整型¶ ............................................................. 28 5.13. 64 位下的可移植性¶ ................................................ 29 5.14. 预处理宏¶ ......................................................... 30 5.15. 0 和 NULL¶ ........................................................ 31 5.16. sizeof¶ ........................................................... 31 5.17. Boost 库¶ ......................................................... 31 6. 命名约定¶ ................................................................ 33 6.1. 通用命名规则¶ ...................................................... 33 6.2. 文件命名¶ .......................................................... 34 6.3. 类型命名¶ .......................................................... 34 6.4. 变量命名¶ .......................................................... 34 6.5. 常量命名¶ .......................................................... 36 6.6. 函数命名¶ .......................................................... 36 6.7. 名字空间命名¶ ...................................................... 36 6.8. 枚举命名¶ .......................................................... 36 6.9. 宏命名¶ ............................................................ 37 6.10. 命名规则的特例¶ ................................................... 37 7. 注释¶ .................................................................... 38 7.1. 注释风格¶ .......................................................... 38 7.2. 文件注释¶ .......................................................... 38 7.3. 类注释¶ ............................................................ 38 7.4. 函数注释¶ .......................................................... 39 7.5. 变量注释¶ .......................................................... 40 7.6. 实现注释¶ .......................................................... 40 7.7. 标点, 拼写和语法¶ .................................................. 41 7.8. TODO 注释¶ ......................................................... 42 译者 (YuleFox) 笔记¶ .................................................... 42 8. 格式¶ .................................................................... 43 8.1. 行长度¶ ............................................................ 43 8.2. 非 ASCII 字符¶ ..................................................... 43 8.3. 空格还是制表位¶ .................................................... 43 8.4. 函数声明与定义¶ .................................................... 44 8.5. 函数调用¶ .......................................................... 46 8.6. 条件语句¶ .......................................................... 47 8.7. 循环和开关选择语句¶ ................................................ 48 8.8. 指针和引用表达式¶ .................................................. 49 8.9. 布尔表达式¶ ........................................................ 49 8.10. 函数返回值¶ ....................................................... 50 8.11. 变量及数组初始化¶ ................................................. 50 8.12. 预处理指令¶ ....................................................... 50 8.13. 类格式¶ ........................................................... 50 8.14. 初始化列表¶ ....................................................... 51 8.15. 名字空间格式化¶ ................................................... 51 8.16. 水平留白¶ ......................................................... 52 8.17. 垂直留白¶ ......................................................... 53 译者 (YuleFox) 笔记¶ .................................................... 54 9. 规则特例¶ ................................................................ 56 9.1. 现有不合规范的代码¶ ................................................ 56
9.2. Windows 代码¶ ...................................................... 56 10. 结束语¶ ................................................................. 58 Google C++ 风格指南 - 中文版 3
Google C++ 风格指南 - 中文版 1 译者前言¶ Google 经常会发布一些开源项目, 意味着会接受来自其他代码贡献者的代码. 但是如果代 码贡献者的编程风格与 Google 的不一致, 会给代码阅读者和其他代码提交这造成不小的困 扰. Google 因此发布了这份自己的编程风格, 使所有提交代码的人都能获知 Google 的编程 风格. 翻译初衷: 规则的作用就是避免混乱. 但规则本身一定要权威, 有说服力, 并且是理性的. 我们所 见过的大部分编程规范, 其内容或不够严谨, 或阐述过于简单, 或带有一定的武断性. Google 保持其一贯的严谨精神, 5 万汉字的指南涉及广泛, 论证严密. 我们翻译该系列 指南的主因也正是其严谨性. 严谨意味着指南的价值不仅仅局限于它罗列出的规范, 更 具参考意义的是它为了列出规范而做的谨慎权衡过程. 指南不仅列出你要怎么做, 还告诉你为什么要这么做, 哪些情况下可以不这么做, 以及 如何权衡其利弊. 其他团队未必要完全遵照指南亦步亦趋, 如前面所说, 这份指南是 Google 根据自身实际情况打造的, 适用于其主导的开源项目. 其他团队可以参照该指 南, 或从中汲取灵感, 建立适合自身实际情况的规范. 我们在翻译的过程中, 收获颇多. 希望本系列指南中文版对你同样能有所帮助. 我们翻译时也是尽力保持严谨, 但水平所限, bug 在所难免. 有任何意见或建议, 可与我们 取得联系. 中文版和英文版一样, 使用 Artistic License/GPL 开源许可. 中文版修订历史: 2009-06 3.133 : YuleFox 的 1.0 版已经相当完善, 但原版在近一年的时间里, 其 规范也发生了一些变化. yospaly 与 YuleFox 一拍即合, 以项目的形式来延续中文版 : Google 开源项目风格指南 - 中文版项目. 主要变化是同步到 3.133 最新英文版本, 做部分勘误和改善可读性方面 的修改, 并改进排版效果. yospaly 重新翻修, YuleFox 做后续评审. 2008-07 1.0 : 出自 YuleFox 的 Blog, 很多地方摘录的也是该版本.   背景¶ C++ 是 Google 大部分开源项目的主要编程语言. 正如每个 C++ 程序员都知道的, C++ 有很 多强大的特性, 但这种强大不可避免的导致它走向复杂,使代码更容易产生 bug, 难以阅读 和维护. 本指南的目的是通过详细阐述 C++ 注意事项来驾驭其复杂性. 这些规则在保证代码易于管 理的同时, 高效使用 C++ 的语言特性. 风格, 亦被称作可读性, 也就是指导 C++ 编程的约定. 使用术语 “风格” 有些用词不当, 因为这些习惯远不止源代码文件格式化这么简单. 使代码易于管理的方法之一是加强代码一致性. 让任何程序员都可以快速读懂你的代码这点 非常重要. 保持统一编程风格并遵守约定意味着可以很容易根据 “模式匹配” 规则来推断
Google C++ 风格指南 - 中文版 2 各种标识符的含义. 创建通用, 必需的习惯用语和模式可以使代码更容易理解. 在一些情况 下可能有充分的理由改变某些编程风格, 但我们还是应该遵循一致性原则,尽量不这么做. 本指南的另一个观点是 C++ 特性的臃肿. C++ 是一门包含大量高级特性的庞大语言. 某些情 况下, 我们会限制甚至禁止使用某些特性. 这么做是为了保持代码清爽, 避免这些特性可能 导致的各种问题. 指南中列举了这类特性, 并解释为什么这些特性被限制使用. Google 主导的开源项目均符合本指南的规定. 注意: 本指南并非 C++ 教程, 我们假定读者已经对 C++ 非常熟悉.
Google C++ 风格指南 - 中文版 3 1. 头文件¶ 通常每一个 .cc 文件都有一个对应的 .h 文件. 也有一些常见例外, 如单元测试代码和只 包含 main() 函数的 .cc 文件. 正确使用头文件可令代码在可读性、文件大小和性能上大为改观. 下面的规则将引导你规避使用头文件时的各种陷阱. 1.1. #define 保护¶ Tip 所有头文件都应该使用 #define 防止头文件被多重包含, 命名格式当是: ___H_ 为保证唯一性, 头文件的命名应该依据所在项目源代码树的全路径. 例如, 项目 foo 中的 头文件 foo/src/bar/baz.h 可按如下方式保护: #ifndef FOO_BAR_BAZ_H_ #define FOO_BAR_BAZ_H_ … #endif // FOO_BAR_BAZ_H_ 1.2. 头文件依赖¶ Tip 能用前置声明的地方尽量不使用 #include. 当一个头文件被包含的同时也引入了新的依赖, 一旦该头文件被修改, 代码就会被重新编译. 如果这个头文件又包含了其他头文件, 这些头文件的任何改变都将导致所有包含了该头文件 的代码被重新编译. 因此, 我们倾向于减少包含头文件, 尤其是在头文件中包含头文件. 使用前置声明可以显著减少需要包含的头文件数量. 举例说明: 如果头文件中用到类 File, 但不需要访问 File 类的声明, 头文件中只需前置声明 class File; 而无须 #include "file/base/file.h". 不允许访问类的定义的前提下, 我们在一个头文件中能对类 Foo 做哪些操作?  我们可以将数据成员类型声明为 Foo * 或 Foo &.  我们可以将函数参数 / 返回值的类型声明为 Foo (但不能定义实现).  我们可以将静态数据成员的类型声明为 Foo, 因为静态数据成员的定义在类定义之 外. 反之, 如果你的类是 Foo 的子类, 或者含有类型为 Foo 的非静态数据成员, 则必须包含 Foo 所在的头文件. 有时, 使用指针成员 (如果是 scoped_ptr 更好) 替代对象成员的确是明智之选. 然而, 这 会降低代码可读性及执行效率, 因此如果仅仅为了少包含头文件,还是不要这么做的好. 当然 .cc 文件无论如何都需要所使用类的定义部分, 自然也就会包含若干头文件. 1.3. 内联函数¶ Tip
Google C++ 风格指南 - 中文版 4 只有当函数只有 10 行甚至更少时才将其定义为内联函数. 定义: 当函数被声明为内联函数之后, 编译器会将其内联展开, 而不是按通常的函数调用机制 进行调用. 优点: 当函数体比较小的时候, 内联该函数可以令目标代码更加高效. 对于存取函数以及其它 函数体比较短, 性能关键的函数, 鼓励使用内联. 缺点: 滥用内联将导致程序变慢. 内联可能使目标代码量或增或减, 这取决于内联函数的大小. 内联非常短小的存取函数通常会减少代码大小, 但内联一个相当大的函数将戏剧性的增 加代码大小. 现代处理器由于更好的利用了指令缓存, 小巧的代码往往执行更快。 结论: 一个较为合理的经验准则是, 不要内联超过 10 行的函数. 谨慎对待析构函数, 析构函 数往往比其表面看起来要更长, 因为有隐含的成员和基类析构函数被调用! 另一个实用的经验准则: 内联那些包含循环或 switch 语句的函数常常是得不偿失 (除 非在大多数情况下, 这些循环或 switch 语句从不被执行). 有些函数即使声明为内联的也不一定会被编译器内联, 这点很重要; 比如虚函数和递归 函数就不会被正常内联. 通常, 递归函数不应该声明成内联函数.(YuleFox 注: 递归调 用堆栈的展开并不像循环那么简单, 比如递归层数在编译时可能是未知的, 大多数编译 器都不支持内联递归函数). 虚函数内联的主要原因则是想把它的函数体放在类定义内, 为了图个方便, 抑或是当作文档描述其行为, 比如精短的存取函数. 1.4. -inl.h 文件¶ Tip 复杂的内联函数的定义, 应放在后缀名为 -inl.h 的头文件中. 内联函数的定义必须放在头文件中, 编译器才能在调用点内联展开定义. 然而, 实现代码理 论上应该放在 .cc 文件中, 我们不希望 .h 文件中有太多实现代码, 除非在可读性和性能 上有明显优势. 如果内联函数的定义比较短小, 逻辑比较简单, 实现代码放在 .h 文件里没有任何问题. 比 如, 存取函数的实现理所当然都应该放在类定义内. 出于编写者和调用者的方便, 较复杂的 内联函数也可以放到 .h 文件中, 如果你觉得这样会使头文件显得笨重, 也可以把它萃取到 单独的 -inl.h 中. 这样把实现和类定义分离开来, 当需要时包含对应的 -inl.h 即可。 -inl.h 文件还可用于函数模板的定义. 从而增强模板定义的可读性. 别忘了 -inl.h 和其他头文件一样, 也需要 #define 保护. 1.5. 函数参数的顺序¶ Tip 定义函数时, 参数顺序依次为: 输入参数, 然后是输出参数. C/C++ 函数参数分为输入参数, 输出参数, 和输入/输出参数三种. 输入参数一般传值或传 const 引用, 输出参数或输入/输出参数则是非-const 指针. 对参数排序时, 将只输入的参 数放在所有输出参数之前. 尤其是不要仅仅因为是新加的参数, 就把它放在最后; 即使是新 加的只输入参数也要放在输出参数.
分享到:
收藏