文章目录

  • 前言
  • 命名约定
    • 类型命名
    • 变量命名
    • 枚举命名
    • 宏的命名
  • 注释
    • 注释风格
    • 文件注释
    • 类注释
    • 函数注释
    • 变量注释
      • 类的数据成员
      • 全局变量
    • 实现注释
    • TODO注释
  • 格式
    • 行长度
    • 空格还是制表符
    • 函数声明和定义
    • lambda表达式
    • 条件语句
    • 指针和引用
    • 变量及数组初始化
    • 预处理指令
    • 构造函数初始化列表
    • 名字空间格式化

前言

本文源自Google C++编程风格指南,砍掉了其中比较common的部分,保留了个人认为最有价值的部分,并合入了自己的理解。原文下载连接:Google C++编程风格指南

命名约定

类型命名

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

变量命名

变量名一律小写,单词之间使用下划线连接。类和结构体的成员变量以m_开头(原文是类的成员变量以_结尾,结构体不用)

枚举命名

枚举的命名应当和宏一致

宏的命名

宏的命名使用全大写字母加下划线,如MY_MACRO

注释

注释风格

使用/*… */风格,每行注释前加*,这样更为美观,阅读起来赏心悦目

文件注释

在每一个文件开头加入版权公告(简单项目可省略),然后是文件内容描述
文件内容:
通常.h文件要对所声明的类的功能和用法做简单说明,.cc文件通常包含了更多的实现细节或算法技巧讨论。不要简单的在.h和.cc文件之间复制注释,这偏离了注释的实际意义

类注释

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

  /* 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 {...
};

如果类有任何同步的前提,需要在文档说明。如果该类的实例可被多线程访问,要特别注意文档说明多线程环境下相关的规则和使用。

函数注释

函数声明处注释描述函数的功能;定义处描述函数的实现
函数声明处注释的内容:

  • 函数的参数,参数的意义,以及是输入参数还是输出参数
  • 函数功能
  • 函数的返回值
  • 函数的注意事项
    如(摘自workflow)
 /*** @brief      register default port for one scheme string* @param[in]  scheme           scheme string* @param[in]  port             default port value* @note       ...* @warning    No effect when scheme is "http"/"https"/"redis"/"rediss"/"mysql"/"kafka"*/static void register_scheme_port(const std::string& scheme, unsigned short port);

这样的代码既美观又清晰
但不要过度注释,那些显而易见用途的函数就不用过多的注释了
函数定义:
重要的函数定义时要说明函数功能和实现要点,比如说说你的编程技巧,实现的大致步骤,或解释为何如何实现

变量注释

类的数据成员

每个类数据成员都应该用注释说明其用途。如:

private:
/* Keeps track of the total number of entries in the table.
* Used to ensure we do not go over the limit. -1 means
* that we don't yet know how many entries the table has.*/
int num_total_entries_;

全局变量

和数据成员一样,所有全局变量也要注释说明含义及用途。如:

/* The total number of tests cases that we run through in this regression test.*/
const int kNumTestCases = 6;

实现注释

对于代码中巧妙的,晦涩的,有趣的,重要的地方加以注释

/* Divide result by two, taking into account that x* contains the carry from the add.*/
for (int i = 0; i < result->size(); i++) {x = (x << 8) + (*result)[i];
(*result)[i] = x >> 1;
x &= 1;
}

TODO注释

对那些临时的、短期的解决方案,或仍有改进空间的代码使用TODO注释
TODO 注释要使用全大写的字符串 TODO, 在随后的圆括号里写上你的大名, 邮件地址, 或其它身份标识. 冒号是可选的. 主要目的是让添加注释的人 (也是可以请求提供更多细节的人) 可根据规范的 TODO 格式进行查找. 添加 TODO注释并不意味着你要自己来修正.

/* TODO(kl@gmail.com): Use a "*" here for concatenation operator. */
/* TODO(Zeke) change this to use relations. */

格式

行长度

每行代码不要过长,影响阅读,如果实在过长,可以用\符号隔断成两行较短的代码行,参考长度为80个字符

空格还是制表符

统一使用4个空格作为缩进,调整你的编辑器来将制表符转为空格

函数声明和定义

返回类型和函数名在同一行, 参数也尽量放在同一行,如果放不下就对形参分行。
过长时可以这样:

ReturnType LongClassName::ReallyReallyReallyLongFunctionName(Type par_name1, // 4 空格缩进Type par_name2,Type par_name3) {DoSomething(); // 2 空格缩进
...
}

注意以下几点:
• 如果返回类型和函数名在一行放不下,分行。
• 如果返回类型那个与函数声明或定义分行了,不要缩进。
• 左圆括号总是和函数名在同一行;
函数名和左圆括号间没有空格;
圆括号与参数间没有空格;
左大括号总在最后一个参数同一行的末尾处;
• 如果其它风格规则允许的话,右大括号总是单独位于函数最后一行,或者与左大括号同一行。
• 右大括号和左大括号间总是有一个空格;
函数声明和定义中的所有形参必须有命名且一致;
• 所有形参应尽可能对齐;
• 换行后的参数保持 4 个空格的缩进;
如果有些参数没有用到, 在函数定义处将参数名注释起来:

/* 接口中形参恒有命名。*/
class Shape {public:
virtual void Rotate(double radians) = 0;
}
/* 声明中形参恒有命名。*/
class Circle : public Shape {public:
virtual void Rotate(double radians);
}
/* 定义中注释掉无用变量。 */
void Circle::Rotate(double /*radians*/) {}
/* 差 - 如果将来有人要实现,很难猜出变量是干什么用的。 */
void Circle::Rotate(double) {}

lambda表达式

不要使用默认捕获!! 且使用lamdba表达式时要注意空悬指针等问题

条件语句

所有情况下 if 和左圆括号间都有个空格. 右圆括号和左大括号之间也要有个空格:

if(condition) /* 差 - IF 后面没空格。*/
if (condition){ /* 差 - { 前面没空格。 */
if(condition){ /* 变本加厉地差。 */
if (condition) { /* 可 - IF 和 { 都与空格紧邻。*/

如果能增强可读性, 简短的条件语句允许写在同一行. 只有当语句简单并且没有使用 else 子句时使用:

if (x == kFoo) return new Foo();
if (x == kBar) return new Bar();

如果有else子语句则不行

/* 不可以这样子 - 当有 ELSE 分支时 IF 块却只有一行*/
if (x) DoThis();
else DoThat();

单行语句也一定要加大括号,这是为了后续如果有改动的话,防止出问题

if (condition) {foo;
}

指针和引用

在声明指针变量或参数时, 星号与变量名紧挨:

/* good */
char *ptr = NULL;
/* bad */
char* ptr = NULL;

这样做是为了防止出现歧义,如

char* ptr1 = NULL, ptr2 = NULL;

这里的ptr2实际是一个char类型,但很容易让人误以为是一个char *类型。

变量及数组初始化

尽量使用{ }形式的初始化,但要小心列表初始化 {…} 用 std::initializer_list 构造函数初始化出的类型。非空列表初始化就会优先调用 std::initializer_list, 不过空列表初始化除外,后者原则上会调用默认构造函数。为了强制禁用std::initializer_list 构造函数,请改用括号。

vector<int> v1(100, 1); /* vector中含有100个元素,每个元素都是个1 */
vector<int> v2{100, 1}; /* vector 中含有2个元素,分别是100和1 */

预处理指令

预处理指令不要缩进, 从行首开始。即使预处理指令位于缩进代码块中, 指令也应从行首开始。

/* 可 - directives at beginning of line */
if (lopsided_score) {#if DISASTER_PENDING  /* 正确 -- 行开头起。 */DropEverything();
#endifBackToNormal();
}
/* 差 - indented directives */
if (lopsided_score) {#if DISASTER_PENDING /* 错了! "#if" 应该放在行开头 */DropEverything();#endif               /* 错了! "#endif" 不要缩进 */BackToNormal();
}

构造函数初始化列表

构造函数初始值列表放在同一行或按四格缩进并排几行
下面两种初始值列表方式都可以接受

/* 当全放在一行合适时: */
MyClass::MyClass(int var) : some_var_(var), some_other_var_(var + 1) {

或者

/* 如果要断成多行,缩进四格,冒号放在第一行初始化句: */
MyClass::MyClass(int var): some_var_(var),               /* 4 空格缩进 */some_other_var_(var + 1) {        /* 对准 */...DoSomething();...
}

名字空间格式化

名字空间 不要增加额外的缩进层次, 名字空间末尾要加注释说明。例如:

namespace wd{void foo() { /* 正确。命名空间内没有额外的缩进。 */
...
}
} /* namespace */

Google C++编程风格指南阅读笔记之命名、注释和格式相关推荐

  1. Google C++编程风格指南

    [译]Google C++编程风格指南(八)[完] 2008年09月03日 星期三 17:06 原文地址:Google C++ Style Guide 规则之例外 前面说明的编码习惯基本是强制性的,但 ...

  2. Google Java编程风格指南(献给那些没有良好编码习惯的程序员们)

    作者:Hawstein 出处:http://hawstein.com/posts/google-java-style.html 声明:本文采用以下协议进行授权: 自由转载-非商用-非衍生-保持署名|C ...

  3. Google C++ 编程风格指南:注释

    Google C++ 编程风格指南:注释 注释虽然写起来很痛苦, 但对保证代码可读性至关重要. 下面的规则描述了如何注释以及在哪儿注释. 当然也要记住: 注释固然很重要, 但最好的代码本身应该是自文档 ...

  4. Google Java编程风格指南中文版

    作者:Hawstein 出处:http://hawstein.com/posts/google-java-style.html 声明:本文采用以下协议进行授权: 自由转载-非商用-非衍生-保持署名|C ...

  5. Google Java编程风格指南中文版(转)

    作者:Hawstein 出处:http://hawstein.com/posts/google-java-style.html 声明:本文采用以下协议进行授权: 自由转载-非商用-非衍生-保持署名|C ...

  6. Google Java编程风格指南

    Hawstein's Blog Home Archive Categories Sitemap About Su 前言 源文件基础 源文件结构 格式 命名约定 编程实践 Javadoc 后记 前言 这 ...

  7. 深度解析Google Java 编程风格指南

    这份文档是Google Java编程风格规范的完整定义.当且仅当一个Java源文件符合此文档中的规则, 我们才认为它符合Google的Java编程风格. 与其它的编程风格指南一样,这里所讨论的不仅仅是 ...

  8. Google C++编程风格指南(一):背景

    Google 的项目大多使用 C++开发.每一个 C++程序员也都知道,C++具有很多强大的语言特性,但这种强大不可避免的导致它的复杂,而复杂性会使得代码更容易出现 bug.难于阅读和维护.   本指 ...

  9. Qt——自定义编程风格指南(未完成)

    文章目录 前言 一.头文件模板规则 1. 尽量所有"#include"放在.h文件头部 2. "#include"包含的类顺序 3. 头文件中 变量.函数 属性 ...

最新文章

  1. CSS 圣杯布局升级版---多个固定宽度一个自适应宽度
  2. AMD芯片支持oracle数据库,oracle 11gR2 amdu 工具可以直接使用
  3. asp.net中@page指令的属性Inherits、Src、CodeBehind区别
  4. 年轻人应该谨记的十点
  5. 将json字符串转换成html,将JSON HTML字符串转换为HTML
  6. UIScollView Touch事件
  7. 增城seo搜索引擎优化_搜索引擎seo优化主要从哪里入手?
  8. PphpStorm常用操作整理
  9. 炫龙dd2——黑苹果10.14 Clover EFI文件共享
  10. android调起浏览器设置头部,Android开发:调起手机浏览器
  11. 室内外地图切换(室内基于ibeacons三点定位)
  12. 使用阿里的easyexcel 导入xls类型Excel文件报错问题深挖
  13. IAR中使用IELFTOOL进行软件代码checksum的生成和添加
  14. DLL的创建和使用(含代码)
  15. 数据库实验4---数据完整性
  16. Trinity使用流程
  17. TIME_WAIT状态和FIN_WAIT_2状态
  18. 灰色关联分析(系统分析+综合评价)
  19. Windbg在软件调试中的应用
  20. coreldraw的线条怎么变成圆头_智能设计 | 建模仿真(3):力学仿真

热门文章

  1. spring BeanDefinition接口
  2. 黑群晖二合一已损毁_搬运 如何在黑群晖中重置损毁的储存池/储存空间
  3. 老周语录-做出好产品的关键
  4. 网易云音乐网络问题修复 (加载失败)
  5. 【每日一题】Leetcode 974
  6. 存储系统 - 存储网络的发展
  7. 商科转码之路 | 算法岗寒假实习面经
  8. refresh方法_Android Shake to Refresh教程
  9. 2024考研《数据结构》复习笔记总览(文末有彩蛋)
  10. com.github.pageHelper 用法