《GOOGLE C++ 编程规范》读书笔记

本文概述了遵循Google C++编程规范的核心原则,包括头文件管理、作用域、类设计、函数和变量命名、注释规范、代码风格等方面,旨在提升代码质量和可维护性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

GOOGLE C++ 规范读书笔记
1、头文件
1、使用#define避免头文件被重复包含,定义的宏为全路径+文件名;
2、能使用前置声明的地方尽量不使用#include。即如果不需要访问类定义的情况下,使用类的前置声明即可;需要类定义时,则必须得包含头文件。
3、只有当函数只有10行甚至更少时才将其定义为内联函数;内联包含循环或switch语句的函数常常是得不尝失(除非在大多数情况下,这些循环或switch语句从不被执行);虚函数和递归函数就不会被正常内联,这是因为内联函数需要编译时就确定函数体,而递归函数在编译时递归层数未知,虚函数不可以内联是为什么?
4、内联函数必须放在头文件中,编译器才能在调用内联函数展开定义。如果内联函数的定义比较复杂,则可以放在后缀名为-inl.h的头文件中;
5、定义函数时,参数顺序依次为:输入参数,然后是输出参数。
6、使用标准的头文件包含顺序可增强可读性,避免隐藏依赖:C库,C++库,其他库的.h,本项目的.h;例如,又如, dir/foo.cc 的主要作用是实现或测试 dir2/foo2.h 的功能, foo.cc 中包含头文件的次序如下:
①dir2/foo2.h (优先位置, 详情如下)
②C 系统文件
③C++ 系统文件
④其他库的 .h 文件
⑤本项目内 .h 文件
这种排序方式可有效减少隐藏依赖. 我们希望每一个头文件都是可被独立编译的 (yospaly 译注: 即该头文件本身已包含所有必要的显式依赖), 最简单的方法是将其作为第一个 .h 文件 #included 进对应的 .cc.

2、作用域

2.1      鼓励在cpp文件内使用匿名名字空间,使用具名的名字空间时,其名称可给予项目名或相对路径,不要使用using关键字。
2.2      C++ 中存在唯一定义原则,注意写注释标示定义的结束
2.3     为什么引用命名空间之后,会导致命名空间中其他函数的都可用,而导致命名空间污染。
2.4     嵌套类定义和使用,除非嵌套类是接口的一部分,否则嵌套类不应该声明为公用的。
2.5     对于非成员函数,静态函数有时不用类封装时,可以使用命名空间来封装。
2.6     局部变量尽可能地在使用的时候声明,在定义的时候进行初始化,同时还要兼顾效率方面的考虑;
2.7     只允许使用plain old data类的静态数据,不允许使用函数返回值初始化静态数据类型
2.8     多线程的全局变量,不要使用class类型(含STL容器),避免不明确行为导致的BUG。
2.9     作用域,除了考虑名字污染,可读性外,主要是为了降低耦合,提高编译/执行效率。

3、类
3.1     如果在构造函数中进行的初始化过于复杂时,建议创建Init()来显式地进行初始化,构造函数禁止调用虚构函数防止不能进行正常的多态;不在构造函数中做太多逻辑相关的初始化;
3.2      如果类中有成员变量,那么最好设置一个默认的构造函数,否则编译器将会为这个类自动生成一个,那将会非常危险;如果继承父类的子类,没有增加数据成员的话,则不需要增加默认构造函数。
3.3      可以使用explicit关键字防止隐式转换,单形参的构造函数都应该声明为explicit;
3.4      指针和引用可以替代copy构造函数和赋值操作符的功能,有时在容器中使用指针或者应用会是一个更好的选择;如果不需要copy构造函数和赋值操作符,那么需要显示地禁止他们 ,即将他们声明为私有的,而不定义;
3.5     当且仅当有数据时,使用struct,其他一律使用classs;
3.6     组合通常比继承更加合适,当必须得是继承的话,则是共有继承;C++中继承分类两类:实现继承和借口继承;如果类中有虚函数,那么类的析构函数最好是虚函数;
3.7     接口是指满足特定条件的类,这些类以Interface为后缀;只有纯虚函数,或者静态函数,不存在非静态函数;不可以直接被实例化;
3.8     尽量少使用重载,模板;
3.9      在头文件中,将存取函数设置为内联函数;
3.10    尽量使函数体控制在一个合理的水平,使程序简短易修改,函数体尽量短小,紧凑,功能单一。

4 GOOGLE 技巧  

4.1     尽量避免使用智能指针,使用时也尽量局部化,安全第一;安全指针的类型;区别scoped_ptr,shared_ptr,auto_ptr
4.2     cpplint.py 是一个用来分析源文件, 能检查出多种风格错误的工具. 它不并完美, 甚至还会漏报和误报, 但它仍然是一个非常有用的工具. 

5 C++ 其他特性

5.1     所有引用传递的参数都应该采用const传递;
5.2     输入参数是值类型或者const ref引用,输出参数是指针类型;
5.3     仅输入参数类型不同,功能相同时使用重载函数。
5.4     不允许使用缺省函数参数;
5.5     尽量不使用变长数组和allocate;
5.6     允许合理使用友元类和友元函数;
5.7     不允许使用C++异常处理;
5.8     Google禁用出于自己项目管理的考虑;
5.9     如果实现根据子类类型来确定执行不同逻辑代码,虚函数无疑更加合适,对象内部就可处理类型识别问题;
5.10     使用C++的类型转化,如static_cast<>().不要使用 int y = (int)x;等转换方式;
5.11     仅在记录日志时,使用流;大多数人选择printf+ read/write;
5.12     对于迭代器和模板类型使用前置自增或者自减;(copy代价过大)
5.13     尽量使用const,mutable可以使用,但是其在多线程中是不安全的;
5.14     使用断言指出变量为非负数,而不是使用无符号型;
5.15     使用宏时要非常谨慎,尽量以内联函数,枚举和常量代替之;
5.16     不要再头文件中定义宏,在马上使用时才进行#define,使用完之后,进行#undef;
5.17     尽可能使用sizeof(varname)代替sizeof(type);
5.18     只使用Boost中被认可的库。

6 命名

6.1     类型和变量最好是名词,函数名最好是动词;除非缩写在其他地方都非常普遍,否则不要缩写;永远不要用省略字母的缩写;
6.2     文件名可以使用小写字母及下划线,或者虚线。源文件采用.cc,头文件采用.h。让文件名非常具体。内联函数最好都在头文件中;
6.3     类型名:首字母大写,不用下划线;
6.4     变量名:小写字母,下划线连接单词;全局变量的最好采用g_来标识;
6.5     采用k开头,作为常量的开头,例如const int kDaysInWeek = 7;
6.6     常规函数使用大小写混合,取值和设值函数则要求与变量名匹配:MyExcitingFunction(), MyExcitingMethod(), my_exciting_member_variable(), set_my_exciting_member_variable(). 
6.7     名字空间命名:采用小写字母,由项目名称+目录组成;
6.8     枚举的命名应当和 常量 或 宏 一致: kEnumName 或是 ENUM_NAME.
6.9      采用大写字母定义宏。

7 注释

7.1     好的程序是自我文档;
7.2     注意注释的一致性,也就是保持一致的注释风格;
7.3     每一个文件都应该包含下列信息:① 版权信息;② 授权信息;③ 原始文件的作者;在这三个信息之下,应该有一段用于描述文件用途的话;不能使头文件和实现文件中注释不能一样,容易造成误解;
7.4     每一个类定义的地方,必须得有该类是如何使用的说明;
7.5     函数声明注释函数功能,以及函数实现;
7.6     通常变量名本身就能很好地说明变量的用途 ,但是有时需要注释一下;类数据成员和全局变量得注释一下说明其用途;
7.7     对代码中巧妙的,重要的,有趣的,不容易懂的地方注释;
7.8     永远不要翻译代码作为翻译,语法和标点都正确的句子对于理解代码大有裨益;
7.9     对于临时,短期的方案,但是还是不够好的,我们采用TODO;
7.10   TODO标示将要进行的工作。   

8 格式  

8.1     每一行代码字符数不超过80个字符;
8.2     尽量不使用非ASCII字符,使用时 必须使用UTF-8编码;
8.3     只使用空格,每次缩进两个空格;
8.4     返回类型和函数名在同一行,参数也尽量在同一行;
返回值总是和函数名在同一行;
左圆括号总是和函数名在同一行;
函数名和左圆括号间没有空格;
圆括号与参数间没有空格;
左大括号总在最后一个参数同一行的末尾处;
右大括号总是单独位于函数最后一行;
右圆括号和左大括号间总是有一个空格;
函数声明和实现处的所有形参名称必须保持一致;
所有形参应尽可能对齐;
缺省缩进为 2 个空格;
换行后的参数保持 4 个空格的缩进;
8.5     尽量将函数调用放在同一行,否则将实参放在圆括号中;
8.6     句点或箭头前后不要有空格键,指针或地址操作符之后不能有空格键;
8.7     函数返回值不要使用圆括号;
8.8     预处理指令不要缩进,从行首开始;
8.9     访问控制块的声明次序依次是:public,protected,private,每次缩进一个空格;
8.10    构造函数初始化列表放在同一行,或者按四格缩进并排几行;
8.11    名字空间内容不要缩进,其内的函数也不要缩进。

9 规则例外

9.1     对于现有不符合既定编程风格的代码可以网开一面;
9.2     不要使用任何非标准的扩展,不到万不得以;
9.3     运用常识和判断力并保持一致。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值