Google Coding Style学习笔记

来源: Google Coding Style Guide 中文版

笔记:

1、

#define 保护

所有头文件都应该使用 #define 来防止头文件被多重包含, 命名格式当是: <PROJECT>_<PATH>_<FILE>_H_ .

为保证唯一性, 头文件的命名应该基于所在项目源代码树的全路径. 例如, 项目 foo 中的头文件 foo/src/bar/baz.h 可按如下方式保护:

#ifndef FOO_BAR_BAZ_H_
#define FOO_BAR_BAZ_H_
…
#endif // FOO_BAR_BAZ_H_           

2、

内联函数

Tip

只有当函数只有 10 行甚至更少时才将其定义为内联函数.

3、

#include 的路径及顺序

Tip

使用标准的头文件包含顺序可增强可读性, 避免隐藏依赖: 相关头文件, C 库, C++ 库, 其他库的 .h, 本项目内的 .h.

 

  1. 避免多重包含是学编程时最基本的要求;
  2. 在 #include 中插入空行以分割相关头文件, C 库, C++ 库, 其他库的 .h 和本项目内的 .h 是个好习惯。

4、

结构体 VS. 类

Tip

仅当只有数据时使用 struct, 其它一概使用 class.

5、

运算符重载

Tip

除少数特定环境外,不要重载运算符.

6、

引用参数

Tip

所有按引用传递的参数必须加上 const.

7、

变长数组和 alloca()

Tip

我们不允许使用变长数组和 alloca().

优点:

变长数组具有浑然天成的语法. 变长数组和 alloca() 也都很高效.

缺点:

变长数组和 alloca() 不是标准 C++ 的组成部分. 更重要的是, 它们根据数据大小动态分配堆栈内存, 会引起难以发现的内存越界 bugs: “在我的机器上运行的好好的, 发布后却莫名其妙的挂掉了”.

结论:

改用更安全的分配器(allocator),就像 std::vector 或 std::unique_ptr<T[]>.

8、

异常

Tip

我们不使用 C++ 异常.

9、

类型转换

Tip

使用 C++ 的类型转换, 如 static_cast<>(). 不要使用 int (int)x 或 int int(x) 等转换方式;

10、

前置自增和自减

Tip

对于迭代器和其他模板对象使用前缀形式 (++i) 的自增, 自减运算符.

定义:

对于变量在自增 (++i 或 i++) 或自减 (--i 或 i--) 后表达式的值又没有没用到的情况下, 需要确定到底是使用前置还是后置的自增 (自减).

优点:

不考虑返回值的话, 前置自增 (++i) 通常要比后置自增 (i++) 效率更高. 因为后置自增 (或自减) 需要对表达式的值 i 进行一次拷贝. 如果 i 是迭代器或其他非数值类型, 拷贝的代价是比较大的. 既然两种自增方式实现的功能一样, 为什么不总是使用前置自增呢?

缺点:

在 C 开发中, 当表达式的值未被使用时, 传统的做法是使用后置自增, 特别是在 for 循环中. 有些人觉得后置自增更加易懂, 因为这很像自然语言, 主语 (i) 在谓语动词 (++) 前.

结论:

对简单数值 (非对象), 两种都无所谓. 对迭代器和模板类型, 使用前置自增 (自减).

11、

const 用法

Tip

我们强烈建议你在任何可能的情况下都要使用 const. 此外有时改用 C++11 推出的 constexpr 更好。

12、

预处理宏

Tip

使用宏时要非常谨慎, 尽量以内联函数, 枚举和常量代替之.

13、

0, nullptr 和 NULL

Tip

整数用 0, 实数用 0.0, 指针用 nullptr 或 NULL, 字符 (串) 用 '\0'.

整数用 0, 实数用 0.0, 这一点是毫无争议的.

对于指针 (地址值), 到底是用 0NULL 还是 nullptr. C++11 项目用 nullptr; C++03 项目则用 NULL, 毕竟它看起来像指针。实际上,一些 C++ 编译器对 NULL 的定义比较特殊,可以输出有用的警告,特别是 sizeof(NULL) 就和 sizeof(0) 不一样。

字符 (串) 用 '\0', 不仅类型正确而且可读性好.

14、

通用命名规则

Tip

函数命名,变量命名,文件命名要有描述性;少用缩写。

尽可能给有描述性的命名,别心疼空间,毕竟让代码易于新读者理解很重要。不要用只有项目开发者能理解的缩写,也不要通过砍掉几个字母来缩写单词。

15、

文件命名

Tip

文件名要全部小写, 可以包含下划线 (_) 或连字符 (-). 按项目约定来. 如果并没有项目约定,”_” 更好。

可接受的文件命名:

* my_useful_class.cc
* my-useful-class.cc
* myusefulclass.cc
* muusefulclass_test.cc // ``_unittest`` 和 ``_regtest`` 已弃用。
16、

类型命名

Tip

类型名称的每个单词首字母均大写, 不包含下划线: MyExcitingClassMyExcitingEnum.

17、

变量命名

Tip

变量名一律小写, 单词之间用下划线连接. 类的成员变量以下划线结尾, 但结构体的就不用,如:: a_local_variablea_struct_data_membera_class_data_member_.

18、

常量命名

Tip

在全局或类里的常量名称前加 k: kDaysInAWeek. 且除去开头的 k 之外每个单词开头字母均大写。

所有编译时常量, 无论是局部的, 全局的还是类中的, 和其他变量稍微区别一下. k 后接大写字母开头的单词:

const int kDaysInAWeek = 7;

这规则适用于编译时的局部作用域常量,不过要按变量规则来命名也可以。

19、

函数命名

Tip

常规函数使用大小写混合, 取值和设值函数则要求与变量名匹配: MyExcitingFunction()MyExcitingMethod()my_exciting_member_variable()set_my_exciting_member_variable().

20、

 文件注释

Tip

在每一个文件开头加入版权公告, 然后是文件内容描述.

法律公告和作者信息:

每个文件都应该包含以下项, 依次是:

  • 版权声明 (比如, Copyright 2008 Google Inc.)
  • 许可证. 为项目选择合适的许可证版本 (比如, Apache 2.0, BSD, LGPL, GPL)
  • 作者: 标识文件的原始作者.

21、

类注释

Tip

每个类的定义都要附带一份注释, 描述类的功能和用法.

// Iterates over the contents of a GargantuanTable.  Sample usage:
//    GargantuanTable_Iterator* iter = table->NewIterator();
//    for (iter->Seek("foo"); !iter->done(); iter->Next()) {
//      process(iter->key(), iter->value());
//    }
//    delete iter;
class GargantuanTable_Iterator {
    ...
};

22、

行长度

Tip

每一行代码字符数不超过 80.

23、

 函数声明与定义

Tip

返回类型和函数名在同一行, 参数也尽量放在同一行,如果放不下就对形参分行。

24、

类格式

Tip

访问控制块的声明依次序是 public:protected:private:, 每次缩进 1 个空格.

posted @ 2017-04-18 16:11  药小药  阅读(596)  评论(0编辑  收藏  举报