浅谈Google C++代码风格

C++作为一门极其复杂的语言,使用好它是十分困难的,C++的灵活语法和复杂特性使得C++变得无比强大,但这也导致它变得十分复杂,曾经我觉得使用越多高级特性的代码就越厉害,而现在我无法赞同,绝大多数情况下,代码的可读性和可维护性是第一位的,而C++正是因此而变成了“最难”的语言,不同人、团队的C++代码风格相差甚远,各种技巧用得飞起,在这种情况下,如果能有一个规范,使得代码尽量统一,就能在一定程度上解决C++代码难以维护的问题。

尽管Google C++代码风格是针对Google自身情况制定的,限制和禁止了很多特性(由于历史原因等),但对于我这种新手,仍十分有帮助。

头文件

  • 一个头文件要自给自足,使用者没有义务知道头文件是否依赖其他的头文件并自行包含。
  • 根据#include头文件的原理,头文件的确是可以用来插入文本的,学习一下。
  • 防止多次包含是常识。
  • 超过10行、递归、含有循环和switch的函数不应内联。
  • 头文件的包含顺序应该是:

    1. 与本文件最相关的头文件
    2. C系统文件
    3. C++系统文件
    4. 其他库的文件
    5. 本项目的文件

      这样可以避免隐藏的依赖,并且保证内部错误及时被发现。

  • 在#include中插入空行分割各类头文件能增加可读性
  • 头文件以绝对路径包含也能增加可读性。
  • 用到的所有头文件都应包含,就算你知道a.h已经被b.h包含了,后来维护的人可不一定知道啊。

作用域

  • 内联命名空间一般只用于跨版本库的兼容性。
  • 命名空间的最后注释出命名空间的名字。
  • 只是为了封装静态成员函数而不共享静态数据创建的类,可用命名空间替代。
  • 尽可能的降低代码耦合性。

  • 避免隐式类型转换,记得加explicit。
  • 分清拷贝和移动,如果你不知道类是否需要拷贝,就不要让类可以拷贝。
  • 继承分清”has-a”和”is-a”,组合 > 实现继承 > 接口继承 > 私有继承,多重继承几乎用不到。
  • 避免重载运算符。
  • 声明次序: public -> protected -> private;

函数

  • 函数尽量短小。
  • 重载函数请保证用户能分清到底调用的是哪个函数,实在不行在函数名里加上参数信息。
  • 避免使用默认参数,默认参数在虚函数中无法正常工作,且会干扰函数指针。

其他C++特性

  • 不用异常,但我认为这只是Google的历史问题,如果是新项目,还是可以用的。
  • 请用断言来保证变量非负,使用无符号型会有bug。
  • size(void *) != sizeof(int),intptr_t才表示一个指针大小的整数。
  • 少用宏,毕竟C++里有内联函数和const变量。
  • sizeof时想清楚想要的是变量的大小还是类型的大小。

命名规范

  • 命名要有描述性。
  • 文件名全小写,用 _ 或 - 分割单词。
  • 类型名每个单词首字母均大写;
  • 普通变量和结构体变量全小写,单词用 _ 分割。
  • 类数据成员在最后接下划线,这一点我认为很好用。
  • 常量开头加k然后每个单词首字母都大写。
  • 函数名也是每个单词首字母都大写。
  • 枚举名要么和常量一样,要么和宏一样(全大写)。

注释

  • 注释要在合适的地方。
  • TODO是个好习惯。

格式

  • 最后有一张图,一看便知。

总结

Google C++代码风格除了命名和格式,别的建议更像是Effective C++系列,有很多坑都在这本书上提过(这可是学C++不可不读的一本特别好的书)。

关于代码风格,最重要的一点就是:

保持一致

代码是给人看的,只要别人看得懂,就是ok的,代码规范也只是一个建议。

最后放一张从网上找来的图,简洁明了地总结了大部分上述知识。

Google C++代码风格