Google C++ 语言规范
1. 命名空间
KeyNotes:
- 鼓励在
.cc文件里使用匿名命名空间或者sttic声明 - 禁止使用内联命令空间,
X::Y::foo等价与X::foo。其主要用于跨版本的ABI兼容问题
namespace X{
inline namespace Y{
void foo();
} // namespace X
} // namespace Y
- 在
.h头文件使用匿名命名空间违背C++的唯一定义原则(ODR)
- 鼓励在
使用建议:
在
namespace的结尾}处添加注释不要在
std命名空间中声明任何东西,包括标准库类的前置声明(行为未定义)禁止使用类似
using namespace foo的语句,会导致污染当前命名空间不要在头文件中使用命名空间别名,除非显示标记内部空间使用。如下是可以的:
namespace paddle{
namespace framework{
using Tensor = paddle::Tensor; // 仅在当前命名空间使用 void foo(){
using LoDTensor = paddle::LoDTensor; // 限制在一个函数内部使用
}
} // namespace framework
} // namespace paddle
2. 匿名命名空间和静态变量
- KeyNotes:
- 当
.cc文件中一个变量不需要被外部使用时(内部链接性),可以将其放在匿名空间或者声明为static。但不要在.h文件中这么做。 - 内部链接性,意味着此函数、变量不能在另一个文件中被访问。即使两个文件中包含了完全相同的标识符,它们指向的也不一样。
- 当
3. 非成员函数、静态成员函数和全局函数
KeyNotes:
- 应尽力避免使用全局函数,取而代之使用静态成员函数,或者命名空间中的非成员函数(避免污染全局作用域)。
- 定义在同一编译单元中的函数,被其他编译单元调用时,可能会引入不必要的耦合和链接依赖。静态成员函数对此尤其敏感,可以考虑提取到新类中,或置于独立库的命名空间中。
使用建议:
定义非成员函数,且只在
.cc文件中使用,使用static关键字修饰,如:static void foo(int x){}
4. 静态和全局变量
- KeyNotes:
- 编译单元:每一个
.c和.cc都是一个编译单元 - 静态生命周期变量:全局变量、静态变量、静态类成员变量和函数静态变量。
- 同一编译单元内是明确的,静态初始化优先于动态初始化,按声明顺序进行,销毁则反着来。
- 不同编译单元的构造和析构顺序是未定义的。
- 编译单元:每一个
- 使用建议:
- 禁止定义静态存储周期非POD变量(如int/char/float类型的结构体等)。因为多编译单元下的静态变量执行时的构造和析构顺序是不明确的。
- 但函数作用域里的静态变量行为是明确的,因为只会在指令执行声明时才会发生。
- 若确实需要一个class类型的静态或者全局变量,注意只能使用raw指针,别用智能指针,因为后者析构时涉及到上下文指出的不定顺序问题。
- 当创建静态变量时,请使用C 数组和
const char[]分别代替vector和string
5. 构造函数
- 使用建议:
- 不要在构造函数中调用虚函数,也不要在无法报错时进行可能失败的初始化
6. 隐式转换
- 使用建议:
- 不要定义隐式类型转换。
- 在转换运算符和单参数构造函数中,请使用
explicit关键字。 - 拷贝和移动构造函数不应当被标记为
explicit,因为他们并不执行类型转换。 - 若一个构造函数包含超过1个参数,不要加
explicit关键字(没有意义);例外情况:除了第一个参数外其他参数都有默认值。 - 接受一个
std::initializer_list作为参数的构造器,也应该省去explicit。
7. 可移动与可拷贝
KeyNotes:
- 可移动及可拷贝类型对象支持值传递方式返回,不同于指针,它不会造成所有权、生命周期、可变性等方面的混乱。
使用建议:
- 不要为基类提供拷贝/赋值操作,因为在使用它们时会造成对象切割。
- 拷贝构造和赋值函数要同时给出或禁用。
8. 继承:
KeyNotes:
- 继承包括实现继承和接口继承:前者子类也继承了父类的实现,后者只继承了接口。
使用建议:
- 优先使用组合,而非继承。如果使用继承,请使用
public - 不要过度使用实现继承,组合更合适一些。
- 若类中包含虚函数,请在析构函数前面加上
virtual关键字 - 在声明重载函数时,请加上
override关键字
- 优先使用组合,而非继承。如果使用继承,请使用
9. 接口:
- KeyNotes:
- 当一个类满足如下条件时,称之为纯接口:
- 只有纯虚函数(
=0)和静态函数 - 没有非静态成员变量
- 没有定义构造函数(若有,也不能带参数,且为
protected)
- 只有纯虚函数(
- 接口不能被实例化(因为没有可调用的构造函数)
- 当一个类满足如下条件时,称之为纯接口:
10. 运算符重载
- KeyNotes:
- 重载operator具有诸多弊端,如无必要,应尽量避免。
- 使用建议:
- 只有在意义明显,且重载行为与内建运算符一致的情况下,可以考虑重载
- 若重载了
<,请也重载>、=
11. 声明顺序
- 使用建议:
- 将相似的声明放在一起。
- 类的定义一般按照
public:、protected:、private:来组织 - 并遵循如下顺序:类型(
typedef、using和嵌套的类与结构体)、常量、工厂函数、构造函数、赋值运算符、析构函数、其他函数、数据成员。
Google C++ 语言规范的更多相关文章
- Google JavaScript 语言规范
变量 ▶ 声明变量必须加上 var 关键字. 常量 ▶ 常量的形式如: NAMES_LIKE_THIS, 即使用大写字符, 并用下划线分隔. 你也可用 @const 标记来指明它是一个常量. 但请 ...
- google的python语言规范
Python语言规范 Lint Tip 对你的代码运行pylint 定义: pylint是一个在Python源代码中查找bug的工具. 对于C和C++这样的不那么动态的(译者注: 原文是less ...
- Python 语言规范(Google)
Python语言规范 Lint tip 对你的代码运行pylint 定义: pylint是一个在Python源代码中查找bug的工具. 对于C和C++这样的不那么动态的(译者注: 原文是less dy ...
- google 谷歌Python语言规范
Python语言规范 https://zh-google-styleguide.readthedocs.io/en/latest/google-python-styleguide/python_lan ...
- 资料推荐--Google Java编码规范
之前已经推荐过Google的Java编码规范英文版了: http://google-styleguide.googlecode.com/svn/trunk/javaguide.html 虽然这篇文章的 ...
- Protocol Buffer技术详解(语言规范)
Protocol Buffer技术详解(语言规范) 该系列Blog的内容主体主要源自于Protocol Buffer的官方文档,而代码示例则抽取于当前正在开发的一个公司内部项目的Demo.这样做的目的 ...
- Google Python命名规范
Google Python命名规范 module_name, 模块 package_name, 包 ClassName, 类 method_name, 方法 ExceptionName, ...
- python公司内部语言规范与语言风格
一.python语言规范 1.1导入 Tip: 仅对包和模块使用导入 定义: 模块间共享代码的重用机制. 优点: 命名空间管理约定十分简单.每个标识符的源都用一种一致的方式指示.x.obj 表示obj ...
- Google Python 命名规范
Google Python命名规范 module_name, 模块 package_name, 包 ClassName, 类 method_name, 方法 ExceptionName, ...
- c#语言规范
0x00 分类 C#语言规范主要有两个来源,即我们熟知的ECMA规范和微软的规范.尽管C#的ECMA规范已经前后修订4次,但其内容仅仅到C# 2.0为止.所以慕容为了方便自己和各位方便查询,在此将常见 ...
随机推荐
- Modbus报文详解
Modbus是一种串行通信协议,最初由Modicon公司(现为施耐德电气的一部分)在1979年为使用其PLC(可编程逻辑控制器)而开发.Modbus已成为工业领域内广泛使用的一种通信协议,特别是对于监 ...
- #线段树#洛谷 4269 [USACO18FEB]Snow Boots G
题目传送门 分析 模型转换一下,能通过当且仅当最长的无法通过段小于 \(d\),(这点应该是此题的精华吧) 那么按照最大深度从小到大排序,双指针在线段树上删除无法通过段,求最长区间即可 代码 #inc ...
- openGauss/MogDB 学习笔记之 -- PITR恢复
openGauss/MogDB 学习笔记之 -- PITR 恢复 概念描述 背景信息 当数据库崩溃或希望回退到数据库之前的某一状态时,MogDB 的即时恢复功能(Point-In-Time Recov ...
- 开发案例:使用canvas实现图表系列之折线图
一.功能结构 实现一个公共组件的时候,首先分析一下大概的实现结构以及开发思路,方便我们少走弯路,也可以使组件更加容易拓展,维护性更强.然后我会把功能逐个拆开来讲,这样大家才能学习到更详细的内容.下 ...
- 推荐几款Vue后台管理系统的框架,以便备用
推荐几款Vue后台管理系统的框架,以便备用 Vue.js 是一个目前比较流行的前端框架,在业界也算很有名气,今天这里为大家罗列一下基于Vue的后端管理的框架. 使用这些框架你会发现它包括了我们常用的路 ...
- mysql 必知必会整理——mysql 介绍[一]
前言 对mysql 进行简介. 正文 mysql 是一种数据库,那么什么是数据库呢? 数据库是一个以某种有组织的方式存储的数据集合. 也就是说数据有某种组织规律的就叫做数据库. 数据库(databas ...
- redis 简单整理——开发和运维中的问题[二十四]
前言 简单介绍一下开发和运维中的问题. 正文 从上文中介绍了,我们有了一个副本了,通过复制的方式. 这些副本可以应用于读写分 离.故障转移(failover).实时备份等场景. 那么可以关注一些开发和 ...
- 重新点亮linux 命令树————查看进程[二十一]
前言 简单介绍一下进程. 正文 进程管理: 进程的概念与进程查看 进程的控制命令 进程的通信方式---信号 守护进程和系统日志 服务管理工具 systemctl SELinux 简介 进程概念: ht ...
- 重学c#系列——缓存[盛派源码分析cache](九)
前言 以前整理过缓存的东西在: https://www.cnblogs.com/aoximin/p/12727659.html 只是粗略的例子,因为真的要去介绍缓存这个东西,要从内存开始,是一个有时间 ...
- shell编程实现用户循环输入
如果你想在Shell脚本中实现一个循环判断用户输入是否正确,并根据情况决定是否退出系统,可以使用一个无限循环(如while true)和条件语句来实现. 以下是一个示例代码,用于演示这种情况: #!/ ...