Google C++ Style

阅读完《Google C++ Style》记录些小要点,很多开源代码都是按照这个规则编码,在了解这些原则之后,个人感觉阅读开源代码应该会省很多力气。

  • 有头文件都应该使用 #define 防止头文件被多重包含, 命名格式当是: _H

  • 能用前置声明的地方尽量不使用 #include
    前置声明是为了降低编译依赖,防止修改一个头文件引发多米诺效应; 举例说明: 如果头文件中用到类 File, 但不需要访问 File 类的声明, 头文件中只需前置声明 class File; 而无须 #include “file/base/file.h”.

  • 只有当函数只有 10 行甚至更少时才将其定义为内联函数.
    当函数被声明为内联函数之后, 编译器会将其内联展开, 而不是按通常的函数调用机制进行调用.优点:当函数体比较小的时候, 内联该函数可以令目标代码更加高效. 对于存取函数以及其它函数体比较短, 性能关键的函数

  • 义函数时, 参数顺序依次为: 输入参数, 然后是输出参数。
    标准化函数参数顺序可以提高可读性和易维护性

  • 造函数体中进行初始化操作
    如果对象需要进行有意义的 (non-trivial) 初始化, 考虑使用明确的 Init() 方法并 (或) 增加一个成员标记用于指示对象是否已经初始化成功.

  • 单个参数的构造函数使用 C++ 关键字 explicit.
    大部分类并不需要可拷贝, 也不需要一个拷贝构造函数或重载赋值运算符. 不幸的是, 如果你不主动声明它们, 编译器会为你自动生成, 而且是 public 的.可以考虑在类的 private: 中添加拷贝构造函数和赋值操作的空实现, 只有声明, 没有定义. 由于这些空函数声明为 private, 当其他代码试图使用它们的时候, 编译器将报错. 方便起见, 我们可以使用 DISALLOW_COPY_AND_ASSIGN 宏:

1
2
3
4
5
6
7
8
9
10
11
12

#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
TypeName(const TypeName&); \
void operator=(const TypeName&)
class Foo {
public:
Foo(int f);
~Foo();

private:
DISALLOW_COPY_AND_ASSIGN(Foo);
};
  • 仅当只有数据时使用 struct, 其它一概使用 class.

  • 编写简短函数
    如果函数超过 40 行, 可以思索一下能不能在不影响程序结构的前提下对其进行分割.

  • 存取控制

将所有数据成员声明为 private, 并根据需要提供相应的存取函数. 例如, 某个名为 foo_ 的变量, 其取值函数是 foo(). 还可能需要一个赋值函数 set_foo().一般在头文件中把存取函数定义成内联函数.

  • 声明顺序

在类中使用特定的声明顺序: public: 在 private: 之前, 成员函数在数据成员 (变量) 前;

通常是:

  • public -> protected -> private;
  • typedefs 和枚举
  • 常量
  • 构造函数
  • 析构函数
  • 成员函数, 含静态成员函数
  • 数据成员, 含静态数据成员
  • 类型转换

使用 C++ 的类型转换, 如 static_cast<>(). 不要使用 int y = (int)x 或 int y = int(x) 等转换方式;
不要使用 C 风格类型转换. 而应该使用 C++ 风格.

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

不考虑返回值的话, 前置自增 (++i) 通常要比后置自增 (i++) 效率更高. 因为后置自增 (或自减) 需要对表达式的值 i 进行一次拷贝. 如果 i 是迭代器或其他非数值类型, 拷贝的代价是比较大的.

  • 尽可能用 sizeof(varname) 代替 sizeof(type).