Google 的 C++ 代码规范

 

Google 开源项目风格指南 (中文版):https://zh-google-styleguide.readthedocs.io/en/latest/
英文版:http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml
中文版:http://zh-google-styleguide.readthedocs.org/en/latest/google-cpp-styleguide/
google c++ 编码规范:http://blog.csdn.net/xiexievv/article/details/50972809
PDF 版下载地址:https://pan.baidu.com/s/1i3gc7lF

 

 

        Google C++ 编码规范很早就已经公开了,李开复也在其微博上公开分享:”我认为这是地球上最好的一份 C++ 编程规范,没有之一,建议广大国内外IT研究使用。“

        Google C++ Style Guide是一份不错的C++编码指南,下面是一张比较全面的说明图,可以在短时间内快速掌握规范的重点内容。不过规范毕竟是人定的,记得活学活用。

 

  1.  保持一致也非常重要,如果你在一个文件中新加的代码和原有代码风格相去甚远的话,这就破坏了文件本身的整体美观也影响阅读,所以要尽量避免。
  2.  一些条目往往有例外,比如下面这些,所以本图不能代替文档,有时间还是把PDF认真阅读一遍吧。

        异常在测试框架中确实很好用

        RTTI在某些单元测试中非常有用

        在记录日志时可以使用流
        操作符重载 不提倡使用,有些STL 算法确实需要重载operator==时可以这么做。

 

注:原图较大,在新标签页中打开或保存到本地打开更清晰

 

 

 

 

头文件

 

  函数参数顺序

  C/C++函数参数分为输入参数和输出参数两种,有时输入参数也会输出(注:值被修改时)。输入参数一般传值或常数引用(const references),输出参数戒输入/输出参数为非常数指针(non-const pointers)。对参数排序时,将所有输入参数置于输出参数之前。不要仅仅因为是新添加的参数,就将其置于最后,而应该依然置于输出参数之前。这一点并不是必须遵循的规则,输入/输出两用参数(通常是类/结构体变量)混在其中,会使得规则难以遵守。

  个人感受:这条规则相当重要,自己写代码的时候可能没有太大感觉,但是在阅读别人代码的时候感觉特别明显。如果代码按照这种规范来写,从某种角度来说,这段代码具有“自注释”的功能,那么在看代码的时候就会比较轻松。Doom3的代码规范中提到,“Use ‘const’ as much as possible”,也是同样的意义。当然,const除了阅读方便以外,还有个很重要的就是防止编码错误,一旦在程序中修改const变量,编译器就会报错,这样就减少了人工出错了可能性,这点尤为重要!

 

  包含文件的名称及次序

  将包含次序标准化可增强可读性、避免隐藏依赖(hidden dependencies,注:隐藏依赖主要是指包含的文件编译),次序如下:C 库、C++库、其他库的.h、项目内的.h。

  项目内头文件应按照项目源代码目录树结构排列,并且避免使用UNIX文件路径.(当前目录)和..(父目录)。 

  举例来说,google-awesome-project/src/foo/internal/fooserver.cc 的包含次序如下: 

  #include "foo/public/fooserver.h" // 优先位置 #include <sys/types.h> #include <unistd.h> #include <hash_map> #include <vector> #include "base/basictypes.h" #include "base/commandlineflags.h" #include "foo/public/bar.h"

  注意,对应的头文件一定要先包含,这样避免隐藏依赖,隐藏依赖的问题不懂的可以去Google,网上有很多资料。另外,《C++编程思想》中提到的包含次序正好相反,从特殊到一般,但是有一点和Google代码规范是一样的,那就是对应的头文件是第一个包含。对于隐藏依赖的问题,以前只是习惯性的把对应的头文件放第一个,没有想过为什么,现在学习了……

 

 

作用域

 

  全局变量

  class 类型的全局变量是被禁止的,内建类型的全局变量是允许的,当然多线程代码中非常数全局变量也是被禁止的。永远不要使用函数返回值初始化全局变量。

  不幸的是,全局变量的构造函数、析构函数以及初始化操作的调用顺序只是被部分规定,每次生成有可能会有变化,从而导致难以发现bug。因此,禁止使用class类型的全局变量(包括STL的string,vector等),因为它们的初始化顺序可能会导致出现问题。内建类型和由内建类型构成的没有构造函数的结构体可以使用,如果你一定要使用class类型的全局变量,请使用单件模式。

 

 

C++类

 

  构造函数的职责

  构造函数中只进行那些没有实际意义的初始化,可能的话,使用Init()方法集中初始化为有意义(non-trivial)的数据。

  个人感受:这种做法可以从一开始就避免一些bug的出现,或更容易解决一些bug。构造函数+Init()函数初始化的方式与只用构造函数的方法相比,对计算机来说他们是没有区别的,但是人是会犯错的,这一条代码规范在某种程度上避免了一些人为错误,这个在开发中特别重要。

 

  拷贝构造函数

  仅在代码中需要拷贝一个类的对象的时候使用拷贝构造函数,不需要拷贝时使用DISALLOW_COPY_AND_ASSIGN这个宏(关于这个宏的内容,可以在网上搜到,我这里就不写了)。C++中对象的隐式拷贝是导致很多性能问题和bugs的根源。拷贝构造函数降低了代码可读性,相比按引用传递,跟踪按值传递的对象更加困难,对象修改的地方变得难以捉摸。

  个人感受:和上一项的目的类似,为了避免人为错误!拷贝构造函数本来是为了方便程序员编程了,但是却有可能成为一个坑,为了避免这类问题,不需要拷贝时使用DISALLOW_COPY_AND_ASSIGN,这样在需要调用拷贝构造函数的时候就会报错,减少了人为出错的可能性。C#和Java在这方面就做得比较好,虽然性能上不如C++,但是人为出错的概率减少了很多。当然,使用一定的代码规范,可以在一定程度上减少C++的坑。

 

  继承

  虽然C++的继承很好用,但是在实际开发中,尽量多用组合少用继承,不懂的去看GoF的《Design Patterns》。

  但重定义派生的虚函数时,在派生类中明确声明其为virtual。这一条是为了为了阅读方便,虽然从语法的角度来说,在基类中声明了virtual,子类可以不用再声明该函数为virtual,但这样一来阅读代码的人需要检索类的所有祖先以确定该函数是否为虚函数o(╯□╰)o。

 

  多重继承

  虽然允许,但是只能一个基类有实现,其他基类是接口,这样一来和JAVA一样了。这些东西在C#和JAVA中都进行了改进,直接从语法上解决问题。C++的灵活性过高,也是个麻烦的问题,只能通过代码规范填坑。

 

  接口

  虚基类必须以Interface为后缀,方便阅读。阅读方便。

 

  重载操作符

  除少数特定情况外,不要重载操作符!!!“==”和“=”的操作Euqals和CopyFrom函数代替,这样更直观,也不容易出错。

  个人感受:看到这一条,我有点惊讶,在学习C++的时候,说重载操作符有神马神马好处,为什么现在又说不要重载操作符呢?仔细看了他的文档,确实说的有道理,导致可能出现的bug见其具体文档。在实际应用中,由于C++的坑实在太多了,不得不把这种“好用”的东西干掉,因为出了bug又找不到,是一件很O疼的事情。

 

  声明次序

  1)typedefs和enums;
  2)常量;
  3)构造函数;
  4)析构函数;
  5)成员函数,含静态成员函数;
  6)数据成员,含静态数据成员。
  宏 DISALLOW_COPY_AND_ASSIGN 置于private:块之后,作为类的最后部分。

 

 

其他 C++ 特性

 

  引用参数

  函数形参表中,所有的引用必须的const!

  个人感受:这么做是为了防止引用引起的误解,因为引用在语法上是值,却有指针的意义。虽然引用比较好用,但是牺牲其某些方面的特性,换来软件管理方面的便利,还是很值得了。

 

  缺省参数

  禁止使用函数缺省参数!

  个人感受:看到这一点的时候觉得有点因噎废食了,其实缺省参数感觉还是蛮好用的。当然从另外一个角度来说,要使用C++就不要怕这种小麻烦,如果因为使用这些特性造成了找不到的bug,那会损失更多时间。

 

  异常

  不要使用 C++异常。

  这一点我没有看懂,也许是因为它的异常机制没有C#和Java那么完善吧……毕竟在C#和Java里面异常还是很好用的东东。

 

  

  除了记录日志,不要使用流,使用printf之类的代替。

  这一条其实是有一些争议的,当然大多数人认为代码一致性比较重要,所以选择printf,具体的可以看原文文档。

 

  const 的使用

  在任何可以的情况下都要使用const。

  这条规则赞一个,Doom3的代码规范里也提到了这一条。这么做有两个好处,一个是防止程序出错,因为修改了const类型的变量会报错;另一个就是方便阅读,使代码“自注释”。虽然这么做也有坏处,当然,总体来说利大于弊。

 

 

命名约定

 

  1、总体规则:不要随意缩写,如果说 ChangeLocalValue 写作ChgLocVal还有情可原的话,把ModifyPlayerName写作MdfPlyNm就太过分了,除函数名可适当为动词外,其他命名尽量使用清晰易懂的名词; 

  2、宏、枚举等使用全部大写+下划线; 

  3、变量(含类、结构体成员变量)、文件、命名空间、存取函数等使用全部小写+下划线,类成员变量以下划线结尾,全局变量以g_开头; 

  4、普通函数、类型(含类与结构体、枚举类型)、常量等使用大小写混合,不含下划线; 

  使用这套命名约定,可以使代码具有一定程度的“自注释”功能,方便他人阅读,也方便自己以后修改。当然3、4两点也可以使用其他的命名约定,只要团队统一即可。

 

格式 

 

  1、行宽原则上不超过80列,把22寸的显示屏都占完,怎么也说不过去;

  2、尽量不使用非ASCII字符,如果使用的话,参考 UTF-8 格式(尤其是 UNIX/Linux 下,Windows 下可以考虑宽字符),尽量不将字符串常量耦合到代码中,比如独立出资源文件,返不仅仅是风格问题了;

  3、UNIX/Linux下无条件使用空格,MSVC的话使用 Tab 也无可厚非; (我没用过Linux,不懂为什么在Linux下无条件使用空格)

  4、函数参数、逻辑条件、初始化列表:要么所有参数和函数名放在同一行,要么所有参数并排分行;

  5、除函数定义的左大括号可以置于行首外,包括函数/类/结极体/枚举声明、各种语句的左大括号置于行尾,所有右大括号独立成行;

  6、./->操作符前后丌留空格,*/&不要前后都留,一个就可,靠左靠右依各人喜好;

  7、预处理指令/命名空间不使用额外缩进,类/结构体/枚举/函数/语句使用缩进;

  8、初始化用=还是()依个人喜好,统一就好;

  9、return不要加();

  10、水平/垂直留白不要滥用,怎么易读怎么来。 

 

 

写在最后

 

  总的来说,这套代码规范还是相当不错的,既有防止错误使用C++的某些特性而导致bugs的规范,又有代码书写的相关规范使其便于阅读,建议搞C++的童鞋都看一看。当然,具体的团队应该会有具体的代码规范,代码风格方面大家可能会有一些区别;不使用C++某些特性(比如不使用C++异常,禁止使用函数缺省参数)方面,应该按照具体情况进行折中处理,而不应该生搬硬套代码规范;但是“不将字符串常量耦合到代码中”这种规范,是大家必须遵守的。

 

 

 

三种编程命名规范(匈牙利命名法、驼峰式命名法、帕斯卡命名法)

 

三种流行的命名法则

目前业界共有四种命名法则:驼峰命名法匈牙利命名法帕斯卡命名法 下划线命名法,其中前三种是较为流行的命名法。

 

 

1 . 匈牙利命名:

 

开头字母用变量类型的缩写,其余部分用变量的英文或英文的缩写,且每个单词的第一个字母都大写。

 

示例: 

int iMyAge;           // i 是 int 类型的缩写。
char cMyName[10];     // c 是 char 类型的缩写。 
float fManHeight;     // f 是 float 类型的缩写。

匈牙利命名广泛应用于象 Microsoft Windows 这样的环境中, Windows 编程中用到的变量(还包括宏)的命名规则都是匈牙利命名法,这种命名技术是由一位能干的 Microsoft 程序员查尔斯- 西蒙尼(Charles Simonyi) 提出的

匈牙利命名法 通过在变量名前面加上相应的小写字母的符号标识作为前缀,标识出变量的作用域,类型等这些符号可以多个同时使用,顺序是先 m_(成员变量), 再指针,再简单数据类型,再其它 。

例如:m_lpszStr, 表示指向一个以0字符结尾的字符串的长指针成员变量 

匈牙利命名法关键是:标识符的名字以一个或者多个小写字母开头作为前缀;前缀之后的是首字母大写的一个单词或多个单词组合,该单词要指明变量的用途 

 

匈牙利命名法中常用的小写字母的前缀:

属性 + 类型 + 描述。属性一般是 小写字母 + :

g_ : 全局变量
m_ : 类成员变量
s_ : 静态变量
c_ : 常量

类 型 前 缀类  型
a   数组 (Array)  
b   布尔值 (Boolean)  
by   字节 (Byte)  
c   有符号字符 (Char),用 c 开头 cCount
cb   无符号字符 (Char Byte,没有多少人用)  
cr   颜色参考值 (ColorRef)  
d   double 用d开头 dDeta
f   float 用f开头 fAvg 
cx,cy   坐标差(长度 ShortInt)  
w   Word,unsigned int(WORD) 用w开头 wCount
dw   Double Word,unsigned long int(DWORD) 用dw开头 dwBroad
fn   函数  
h   Handle(句柄)  
i   整型 int ,用 i 开头 iCount
n   short int  短整型  用 n 开头 nStepCount
l   Long Int   长整型  用 l 开头 lSum
lp   Long Pointer  
m_   类的成员  
np   Near Pointer  
p   Pointer  
s   字符串类型,用s开头 sFileName
sz   以null做结尾的字符串型 (String with Zero End),
   用\0结尾的字符串 用sz开头 szFileName

 

 

2 . 驼峰式命名法(小驼峰式 命名法):

 

小驼峰法(camel方法):第一个单词 以小写字母开始;第二个单词的首字母大写,或从第二个单词开始,后面的每一个单词的首字母都采用大写字母, 小驼峰式命名法: 第一个单词首字母小写,后面其他单词首字母大写。

变量 一般用 小驼峰法标识。

ex: 
int myAge; 
char myName[10]; 
float manHeight;

 

小驼峰式 命名规则(第一个单词首字母小写,后面所有单词的首字母都大写):firstName, camelCase

大驼峰式 命名规则(所有单词的首字母都大写):FirstName, CamelCase

 

下面是分别用 骆驼式命名法下划线法命名 的同一个函数:

printEmployeePaychecks();    骆驼式命名法 ----  函数名中的每一个逻辑断点都有一个大写字母来标记
print_employee_paychecks();下划线法         ----  函数名中的每一个逻辑断点都有一个下划线来标记。

 

 

3 . 帕斯卡命名法(大驼峰式 命名法):

 

帕斯卡命名法(pascal方法)又叫 大驼峰式命名法。相比小驼峰法,大驼峰法把第一个单词的首字母也大写了, 每个单词的第一个字母都大写。 骆驼命名法是首字母小写,而帕斯卡命名法是首字母大写

(pascal方法)常用于 类名,函数名,属性,命名空间

大驼峰法(Upper Camel Case) ex: 
int MyAge; 
char MyName[10]; 
float ManHeight ;
public class DataBaseUser

 

 

4. 下划线 命名规则

 

下划线法是随着 C语言 的出现流行起来的,在 UNIX/LIUNX 这样的环境,以及 GNU 代码中使用非常普遍 

 

 

5. 命名规则 小结:

 

MyData 就是一个帕斯卡命名的示例 。
而 myData 是一个骆驼命名法,它第一个单词的第一个字母小写,后面的单词首字母大写,看起来像一个骆驼 。
而 iMyData 是一个匈牙利命名法,它的小写的i说明了它的型态,后面的和帕斯卡命名相同,指示了该变量的用途。

 

通常每种语言都有自己的 Coding Style,比如 C/C++ 和 python 是下划线,java 和 go 是驼峰。

所以,对于要使用哪种命名法可以根据个人的代码编写风格,也是可使用不同的命名规范混合使用。

如:骆驼 + 下划线 (int temperature_Sensor;)

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/496281.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

NASA投资有远景技术,有望改变未来人类和机器人的勘探任务

来源&#xff1a; 机器人创新生态据NASA官网报道&#xff0c;美国宇航局(NASA)正在投资有远见的技术概念&#xff0c;包括流星撞击探测、太空望远镜群以及细小轨道碎片测绘技术&#xff0c;这些技术将来可能被用于未来的太空探索任务中。美国宇航局已经选出25个还处于早期的技术…

人工智能如何影响社会经济:关于近期文献的一个综述

作者&#xff1a;陈永伟 文章来源&#xff1a;经济学原理 相比于之前的历次技术进步&#xff0c;“人工智能革命”所引发的冲击更为巨大&#xff0c;其对经济学造成的影响也将更为广泛和深远。人工智能技术的突飞猛进&#xff0c;对经济社会的各个领域都产生了重大影响&#…

Spring Data JPA 从入门到精通~Naming命名策略详解及其实践

Naming 命名策略详解及其实践 用 JPA 离不开 Entity 实体&#xff0c;我都知道实体里面有字段映射&#xff0c;而字段映射的方法有两种&#xff1a; 显式命名&#xff1a;在映射配置时&#xff0c;设置的数据库表名、列名等&#xff0c;就是进行显式命名&#xff0c;即通过 C…

激光雷达:从光电技术角度看自动驾驶

来源&#xff1a; 传感器技术激光雷达和与之竞争的传感器技术&#xff08;相机、雷达和超声波&#xff09;加强了对传感器融合的需要&#xff0c;也对认真谨慎地选择光电探测器、光源和MEMS振镜提出了更高的要求。传感器技术、成像、雷达、光探测技术及测距技术&#xff08;激光…

socket的长连接、短连接、半包、粘包与分包

socket的半包&#xff0c;粘包与分包的问题和处理代码&#xff1a;http://blog.csdn.net/qq_16112417/article/details/50392463 知乎关于长连接和短连接&#xff1a;https://www.zhihu.com/search?typecontent&q长连接%20短连接 TCP网络通讯如何解决分包粘包问题&#…

2018年中国人工智能行业研究报告|附下载

来源&#xff1a;网络大数据、艾瑞咨询广义人工智能指通过计算机实现人的头脑思维所产生的效果&#xff0c;是对能够从环境中获取感知并执行行动的智能体的描述和构建;相对狭义的人工智能包括人工智能产业(包含技术、算法、应用等多方面的价值体系)、人工智能技术(包括凡是使用…

Spring Data JPA 从入门到精通~方法的查询策略设置

方法的查询策略设置 通过下面的命令来配置方法的查询策略&#xff1a; EnableJpaRepositories(queryLookupStrategy QueryLookupStrategy.Key.CREATE_IF_NOT_FOUND) 其中&#xff0c;QueryLookupStrategy.Key 的值一共就三个&#xff1a; Create&#xff1a;直接根据方法名…

不用地图如何导航?DeepMind提出新型双路径强化学习「智能体」架构

来源&#xff1a;deepmind、arXiv作者&#xff1a;Piotr Mirowski、Matthew Koichi Grimes、Mateusz Malinowski、Karl Moritz Hermann、Keith Anderson、Denis Teplyashin、Karen Simonyan、Koray Kavukcuoglu、Andrew Zisserman、Raia Hadsell「雷克世界」编译&#xff1a;嗯…

C 和 C++ 宏 详解

From&#xff1a;https://www.cnblogs.com/njczy2010/p/5773061.html C中的预编译宏详解&#xff1a;http://www.cppblog.com/bellgrade/archive/2010/03/18/110030.html C语言的宏总结&#xff1a;http://blog.csdn.net/pirlck/article/details/51254590 C 语言中的 宏定义…

Spring Data JPA 从入门到精通~查询方法的创建

查询方法的创建 内部基础架构中有个根据方法名的查询生成器机制&#xff0c;对于在存储库的实体上构建约束查询很有用&#xff0c;该机制方法的前缀 find…By、read…By、query…By、count…By 和 get…By 从所述方法和开始分析它的其余部分&#xff08;实体里面的字段&#x…

人工智能在能源行业的5个应用

作者&#xff1a;CB Insights . 来源&#xff1a;CometLabs摘要&#xff1a;自2012年以来&#xff0c;把人工智能和能源产业放在一起进行报道的新闻开始增多。本文简要描述了人工智能在能源行业的5个应用方向&#xff0c;及对应的案例。能源行业会产生大量的数据。为了将这些数…

VMware 安装 win7、win10、MAC 和网络模式VMnet0、VMnet1、VMnet8解释

VMware虚拟机安装ghost win7系统方法&#xff1a;http://www.xitongcheng.com/jiaocheng/xtazjc_article_15314.html VMWare14 安装Mac OS系统&#xff08;图解&#xff09;&#xff1a;http://blog.csdn.net/u011415782/article/details/78505422 虚拟机&#xff08;VMware …

Spring Data JPA 从入门到精通~关键字列表

注意除了 find 的前缀之外&#xff0c;我们查看 PartTree 的源码&#xff0c;还有如下几种前缀&#xff1a; private static final String QUERY_PATTERN "find|read|get|query|stream"; private static final String COUNT_PATTERN "count"; private s…

当科学遇上众包:9个值得关注的前沿科技算力众包平台

来源&#xff1a; 资本实验室 . 作者&#xff1a;李鑫找到癌症治疗的方法&#xff0c;预测气候的变化&#xff0c;追踪可能与地球相撞的小行星……甚至预测地震&#xff0c;我们每天都面临着各种世界性难题。如果你想参与解决这些难题&#xff0c;公民科学应用将让你发挥作用…

htop 命令详解

htop 官网&#xff1a;http://htop.sourceforge.net/ Linux top 命令的用法详细详解&#xff1a;https://www.cnblogs.com/zhoug2020/p/6336453.html htop 使用详解&#xff1a;https://www.cnblogs.com/programmer-tlh/p/11726016.html 使用 yum 无法直接安装 htop&#xff…

linux主机服务器日志采集,Linux通过Rsyslog搭建集中日志服务器

(一)Rsyslog简介ryslog 是一个快速处理收集系统日志的程序&#xff0c;提供了高性能、安全功能和模块化设计。rsyslog 是syslog 的升级版&#xff0c;它将多种来源输入输出转换结果到目的地。rsyslog是一个开源工具&#xff0c;被广泛用于Linux系统以通过TCP/UDP协议转发或接收…

IDC预测2022年全球智能家居连接设备市场规模将达10亿台!

来源&#xff1a; IDC官网、智慧生活&#xff1b; 物联网资本论编译摘要&#xff1a;2017年&#xff0c;全球智能家居连接设备市场规模达到43310万台&#xff0c;比上一年增长27.6&#xff05;。2022年市场达到9.397亿台&#xff0c;IDC预计复合年增长率&#xff08;CAGR&#…

effective C++ 读书笔记

本篇文章都是摘自 《Effective C》 中文版 第三版 和 第二版。 再好的记性也有忘记的一天&#xff0c;记录下以备随时查看。。。 电子书下载地址&#xff1a;https://download.csdn.net/download/freeking101/10278088 《Effective C》第二版在线教程&#xff1a;http://www.…

Spring Data JPA 从入门到精通~思维导图

#原图 System.out.println("https://www.processon.com/view/61c7227c0e3e7474fb9b4b76?fromnew1");

高通5G版图现身!你的网络生活将迎来巨变?

来源&#xff1a;36Kr 作者&#xff1a;桐由于骁龙845移动平台和骁龙636移动平台的首发&#xff0c;3月的手机市场对于持币代购的消费者而言注定是充满期待的&#xff0c;在三星S9和红米Note5刷屏之时&#xff0c;曾经隐身手机幕后的高通也再一次引发用户热议&#xff0c;高通…