Google编程规范

news2024/11/7 21:03:40

Google编程规范总结

    • 一、前言
    • 二、头文件
    • 三、类
        • 构造函数
        • 可拷贝类型和可移动类型
        • struct和class
        • 接口
        • 存取控制和声明顺序
    • 四、来自Google的奇技
        • 所有权与智能指针
        • cpplint
    • 五、其他C++特性
    • 六、命名约定(重点)
    • 七、注释(重点)
    • 八、代码格式(重点)
    • 九、结束语

一、前言

  昨天听了雷军的演讲,感受还是很多的,最大的感想就是我之前很喜欢的一句话:在奋力往前走的时候别忘了有时要抬头看看天。努力很重要,甚至是非常重要,但是方向和把握机会的能力也是至关重要的。
最近在看Google Style Guide,感觉得记录一下,来规范一下自己在写C++程序时候的习惯,最近也是放假在家闲出毛病来了,想着提升下自己。


距离6个月,我终于在今天(20230105)把这个坑填上了,希望大家喜欢。重点可以看看第六部分的命名规范,文件命名,类型命名,变量命名,函数命名。
可以的话希望大家点点赞或者关注哟!

二、头文件

  1. self-contain 头文件:就是头文件要能自给自足,也就是要包含它所需要的所有其他的头文件
  2. define保护:所有头文件都要有#define来保护头文件被多重包含,为保证唯一性, 头文件的命名应该基于所在项目源代码树的全路径,例如:项目 foo 中的头文件 foo/src/bar/
    baz.h 可按如下方式保护:
    #ifndef FOO_BAR_BAZ_H_
    #define FOO_BAR_BAZ_H_#endif // FOO_BAR_BAZ_H_
    
  3. 尽量避免使用前置声明:所谓「前置声明」(forward declaration)是类、函数和模板的纯粹声明,没伴随着其定义。
    具体的定义和说明:forword declaration
    类的前置声明只是告诉编译器这是一个类型,但无法告知类型的大小,成员等具体内容。在未提供完整的类之前,不能定义该类的对象,也不能在内联成员函数中使用该类的对象。而头文件则一一告之。
  4. 内联函数:函数只有10行甚至更少的时候才将其定义为内联函数。当函数被声明为内联函数之后, 编译器会将其内联展开, 而不是按通常的函数调用机制进行调用。对于存取函数以及其它函数体比较短, 性能关键的函数, 鼓励使用内联.内联那些包含循环或 switch 语句的函数常常是得不偿失
  5. include的路径和顺序:相关头文件, C 库, C++ 库, 其他库的 .h, 本项目内的 .h,他们之间一般是用插入空行来区分。
    平台特定的条件编译一般是放在其他 include 之后。(有人提出把库文件放在最后,这样出错先是项目内的文件)。

三、类

构造函数

  1. 不要在构造函数中进行复杂的初始化,因为构造函数很难上报错误,不能使用异常,操作失败会造成对象初始化失败,进入不确定状态。
  2. 对单个参数的构造函数使用explicit关键字来避免隐式转换,这一规则也适用于除第一个参数以外的其他参数都具有默认参数的构造函数,例如Foo::Foo(string name, int id = 42).

可拷贝类型和可移动类型

  1. 如果你的类型需要, 就让它们支持拷贝/ 移动. 否则, 就把隐式产生的拷贝和移动函数禁用.
    可拷贝:** 拷贝操作一般通过拷贝构造函数与拷贝赋值操作符定义**,
    可移动:移动操作一般是通过移动构造函数和移动赋值操作符实现的.
  2. 如果你的类不需要拷贝/ 移动操作, 请显式地通过 = delete 或其他手段禁用之

struct和class

仅当只有数据时使用struct,其余时间一概用class。
为了和 STL 保持一致, 对于仿函数和 trait 特性可以不用 class 而是使用 struct.
对于如何实现trait类型可以看这篇文章:trait类型

接口

  1. 接口需要满足以下条件:
    只有纯虚函数 (“=0”) 和静态函数 (除了下文提到的析构函数)
    没有非静态数据成员.
    没有定义任何构造函数. 如果有, 也不能带有参数, 并且必须为 protected
    如果它是一个子类, 也只能从满足上述条件的类继承

存取控制和声明顺序

说白了就是数据成员声明为private,然后为每个数据成员写set和get函数来进行控制。
在类中使用特定的声明顺序: public: 在 private: 之前, 成员函数在数据成员 (变量) 前;

四、来自Google的奇技

(书上是这么翻译的,感觉挺有意思的)

所有权与智能指针

动态分配出的对象最好有单一且固定的所有主,然后通过智能指针传递所有权。
可以把智能指针当成一个重载了 * 和 -> 的「对象」来看。。std::unique_ptr 是 C++11 新推出的一种智能指针类型,用来表示
动态分配出的对象的「独一无二」所有权;当 std::unique_ptr 离开作用域,对象就会被销毁。
不能复制 std::unique_ptr, 但可以把它移动(move)给新所有主。std::shared_ptr 同样表示动态分配对象的所有权,但可以被共享,也可以被复制;对象的所有权由所有复制者共同拥有,最后一个复制者被销毁时,对象也会随着被销毁。

如果对性能要求比较高且此对象是不可更改的(比如说 std::shared_ptr< const Foo >),这时可以用共享所有权来避免昂贵的拷贝操作

cpplint

一个用来检查风格错误的程序,我找个机会专门写一篇文章介绍使用

五、其他C++特性

(这本书暂时只到了C++11)

  1. 所有按引用传递的参数尽量加上const
  2. 只在定义移动构造函数与移动赋值操作时使用右值引用,右值引用使得编写通用的函数封装来转发其参数到另外一个函数成为可能, 无论其参数是否是临时对象都能正常工作,右值引用能实现可移动但不可拷贝的类型, 这一特性对那些在拷贝方面没有实际需求, 但有时又需要将它们作为函数参数传递或塞入容器的类型很有用(完美转发)
  3. 缺省参数:尽可能使用函数重载来代替缺省参数,缺省参数会干扰函数指针,害得后者的函数签名(function signature)往往对不上所实际要调用的函数签名。(这一条可以当成一个考虑项而不是必须项)
  4. 类型转换:
    尽量使用 C++ 的类型转换, 如 static_cast<>(). 不要使用 int y = (int)x 或 int y = int(x) 等转换方式
  5. 强烈建议你在任何可能的情况下都要使用 const. 此外有时改用 C++11 推出的 constexpr 更好。
  6. 用户自定义类型也可以定义接收 std::initializer_list 的构造函数和赋值运算符,来实现可以通过初始化列表构造。
  7. Lambdas, std::functions 和 std::bind 可以搭配成通用回调机制,这一点使用非常多
  8. 不要使用复杂的模板编程(本菜鸡觉得非常有道理)

六、命名约定(重点)

  1. 通用命名规则:尽可能给有描述性的命名,别心疼空间,毕竟让代码易于新读者理解很重要。不要用只有项目开发者能理解的缩写,也不要通过砍掉几个字母来缩写单词,例如:
int price_count_reader; // 无缩写
int num_errors; // “num” 本来就很常见
int num_dns_connections; // 人人都知道 “DNS” 是啥
int n; // 莫名其妙。
int nerr; // 怪缩写。
int n_comp_conns; // 怪缩写。
int wgc_connections; // 只有贵团队知道是啥意思。
int pc_reader; // "pc" 有太多可能的解释了。
int cstmr_id; // 有删减若干字母。
  1. 文件命名:文件名要全部小写, 可以包含下划线 (_) 或连字符 (-),最好使用下划线。不要使用已经存在于 /usr/include 下的文件名,通常应尽量让文件名更加明确。定义类时文件名一般成对出现, 如foo_bar.h 和 foo_bar.cc
  2. 类型命名:类型名称的每个单词首字母均大写, 不包含下划线: MyExcitingClass, MyExcitingEnum。
  3. 变量命名:变量名一律小写, 单词之间用下划线连接. 类的成员变量以下划线结尾,结构体变量不需要下划线结尾。
  4. 常量命名:在全局或类里的常量名称前加 k,且除去开头的 k 之外每个单词开头字母均大写,例如:kDaysInAWeek
  5. 函数命名:常规函数的每个单词首字母大写, 没有下划线,取 值 和 设 值 函 数 则 要 求 与 变 量 名 匹 配(get和set函数,例如:set_num_entries)。
  6. 名字命名空间:用小写字母命名, 并基于项目名称和目录结构: google_awesome_project
  7. 枚举命名:与常量或者宏命名一致,前面加k或者全部大写,(kEnumName 或是 ENUM_NAME)。
    总结:函数命名和类型命名比较像,一般都是首字母全部大写且不使用下划线。常量命名比较特殊,前面加k且后面的首字母全部大写。变量名全部是小写,使用下划线连接。

七、注释(重点)

  1. 注释风格:使用 // 或 /* */, 统一就好.
  2. 文件注释: 在每一个文件开头加入版权公告, 然后是文件内容描述。
    在这里插入图片描述
  3. 类注释:每个类的定义都要附带一份注释, 描述类的功能和用法
  4. 函数注释:函数声明处注释描述函数功能; 定义处描述函数实现.
  5. 变量注释:通常只注释重要的或者是通过名字无法确定用途的变量
  6. TODO注释:对那些临时的, 短期的解决方案, 或已经够好但仍不完美的代码使用 TODO 注释,TODO 注释要使用全大写的字符串 TODO, 在随后的圆括号里写上你的大名, 邮件地址, 或其它身份标识.

八、代码格式(重点)

我对这部分进了删减,因为现在大部分开发工具都能进行一键格式化代码,所以针对格式,前面的命名规范比较重要。

  1. 条件语句:
if (condition) {
	... // 2 空格缩进。
} else { // else 与 if 的右括号同一行。
	...
}
  1. switch和case语句:
switch (var) {
	case 0: { // 2 空格缩进
		... // 4 空格缩进
		break;
	}
	case 1: {
		...
		break;
	}
	default: {
		assert(false);
	}
}
  1. 指针和引用:句点或箭头前后不要有空格. 指针/地址操作符 (*, &) 之后不能有空格.
  2. 命名空间内容不缩进。

九、结束语

  风格指南的重点在于提供一个通用的编程规范, 这样大家可以把精力集中在实现内容而不是表现形式上. 我们展示了全局的风格规范, 但局部风格也很重要, 如果你在一个文件中新加的代码和原有代码风格相去甚远, 这就破坏了文件本身的整体美观, 也影响阅读, 所以要尽量避免。

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

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

相关文章

猪齿鱼知识沉淀

数据源知识沉淀 1、下拉框与Lov的注意点&#xff1a; 下拉框 {name: intertradeType,lookupCode: "HCMS.INTERTRADE_TYPE",label: intl.get(${prefix}.table.intertradeType).d(贸易性质),required: true, }, {name: intertradeTypeMeaning,label: intl.get(${pref…

2023 docker安装gitlab-ce

公司搭建私服git来管理代码。这里使用docker来安装gitlab&#xff0c;过程相对简单。需要服务器至少有4g内存。这里安装的gitlab-ce社区版。前提是安装了docker 安装gitlab-ce 下载镜像&#xff0c;等待下载… docker pull gitlab/gitlab-ce:latest建立了目录 /opt/docker/git…

基础知识一览

这里写目录标题1.类1.1 类和对象的关系1.2 构造函数1.2.1 概念1.2.1.1 修饰符1.2.1.2 返回值类型1.2.1.3 函数名1.2.1.4 参数列表1.2.1.5 return语句1.2.1.6 扩展2.继承2.1 继承的好处和限制2.2 子父类中定义了一模一样的成员变量1.类 1.1 类和对象的关系 类是对象的抽象,对象…

利用宝塔配置jdk环境

首先&#xff0c;下载linux对应版本jdk(注意是Linux版本)&#xff0c;然后通过宝塔传到服务器上。选择相应的jdk文件&#xff0c;将其从本机上传到服务器上的对应文件夹。 上传后可以看到对应如下&#xff1a; 然后将其解压到对应的目录下&#xff0c;使用如下命令&#xff1…

使用Jmeter轻松实现AES加密测试

大家在自己公司做接口测试的时候&#xff0c;有没有遇到过接口做加密处理的情况呢&#xff1f;相信我们的读者朋友们都有一定的概率会遇到这种情况&#xff0c;尤其是对接口数据安全有一定要求的公司接口数据一定会做加密处理。那么遇到加密情况&#xff0c;大家使用工具JMeter…

CAD快速看图怎么转换成PDF格式?这一款软件就足够

CAD快速看图怎么转换成PDF格式&#xff1f;CAD文件是一种比较专业的文件&#xff0c;一般用于设计、绘图等&#xff0c;这种文件需要特殊的软件才可以打开&#xff0c;不过对于大多数人来说&#xff0c;都很少会安装这种软件&#xff0c;因为下载和安装软件需要很多时间&#x…

【计算机视觉】OpenCV 4高级编程与项目实战(Python版)【2】:操作像素

像素是构成图像的基本单位。现在看图1所示的花卉图像,这幅图看着很细腻,不过将图像的白框区域放大,会看到如图2所示的效果,细腻的图像不见了,取而代之的是一个一个的小方块,每一个小方块就是一个像素。 图6 花卉 图7 放大的花卉局部

分库分表解决方案

前言 因为每个学校学生用餐人数太多&#xff0c;一天订单20万量增长&#xff0c;而且学校使用也在不停的增多&#xff0c;公司最近在搞分库分表&#xff0c;数据分离到不同的库中或表中&#xff0c; 所以这段时间了解过数据库的分库分表&#xff0c;也读过很多大神写的博文&…

elasticsearch 7.9.3知识归纳整理(五)之es的索引生命周期管理

es的索引生命周期管理 一、常见概念及命令 1.1、概念 ILM定义了四个生命周期阶段&#xff1a; Hot&#xff1a;正在积极地更新和查询索引。 Warm&#xff1a;不再更新索引&#xff0c;但仍在查询。 cold&#xff1a;不再更新索引&#xff0c;很少查询。信息仍然需要可搜索&…

【蓝桥杯基础题】2021年省赛填空题—卡片

&#x1f451;专栏内容&#xff1a;蓝桥杯刷题⛪个人主页&#xff1a;子夜的星的主页&#x1f495;座右铭&#xff1a;前路未远&#xff0c;步履不停 目录一、题目背景二、题目描述三、题目分析1.检查思路2.思路优化四、代码汇总1.C语言代码2. C代码3.运行结果五、总结1.枚举思…

“强鹰”会议纪要发布,不会停止加息?风险资产恐将承压

美联储发布了去年12月的会议纪要&#xff0c;详细揭露了货币政策制定者对经济和加息路径的最新研判&#xff0c;继续展现偏鹰的论调和立场。 纪要显示&#xff0c;美联储官员致力于抗击通货膨胀&#xff0c;并预计在取得更多进展之前利率将继续上升&#xff0c;并维持“一段时间…

82.Zabbix之Linux服务器agent监控(不需要联网)

Zabbix版本:6.2.3 官网上下载对应的agent

C#中的多线程(一)

一、多线程的术语 在学习多线程之前需要先理解有关多线程的术语。 CPU&#xff08;中央处理器&#xff09;或内核/核心是实际执行程序的硬件单元。许多现代CPU都支持同时多线程&#xff08;Intel称之为超线程&#xff09;&#xff0c;即使一个CPU能表现为多个「虚拟」CPU。进…

Linux安装xFormers教程

参考文章&#xff1a;手把手教你在linux中手动编译并安装xformers 作者&#xff1a;青空朝颜モ出处&#xff1a;bilibili 官方安装方法 官方仓库传送门&#xff1a;https://github.com/facebookresearch/xformers.git 官方给了两种方式安装xFormers&#xff0c;这里给出官方仓…

数字化转型之数字化和业务化论证

引言 数据业务化的本质是数据的产品化、商业化与价值化。主要强调产品化、新业务和专业化运作,也就是以数据为主要内容和生产原料,打造数据产品,按照产品定义、研发、定价、包装和推广的套路进行商业化运作,把数据产品打造成能为企业创收的新兴业务。 数字化是信息技术发…

NodeJs中使用Express开发web项目

文章目录1. web开发模式1.1 服务端渲染的Web开发模式1.2 前后端分离的Web开发模式1.3 如何选择web开发模式2. 身份认证2.1 Session认证机制2.1.1 cookie2.1.2 cookie认证2.1.3 在Express中使用Session认证2.1.4 Session认证的局限性2.2 JWT认证机制2.2.1 JWT组成部分2.2.2 在No…

mysql优化实战

空气质量小时索引顺序先站点后时间 索引情况 根据时间范围查询索引失效 EXPLAIN SELECT station_code, station_name, data_time, aqi, pm25, pm10, o3, no2, so2, co, primary_pollutant, create_date FROM wuhaiyizhangtu.t_air_pollution where data_time between 2022-1…

Node.js 中 session验证登录

在前一篇内容中讲到这个cookie实现验证登录&#xff0c;cookie是存储在客户端的&#xff0c;而session是存储在服务器的&#xff0c;相比较session的安全性会更高&#xff0c;session对象存储特定用户会话所需要的属性以及配置信息&#xff0c;服务通过session对象将用户的信息…

【力扣刷题】day3-4. 寻找两个正序数组的中位数

力扣刷题笔记day3 4. 寻找两个正序数组的中位数 题意 给定两个大小分别为 m 和 n 的正序&#xff08;从小到大&#xff09;数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。 算法的时间复杂度应该为 O(log (mn)) 。 输入&#xff1a;nums1 [1,3], nums2 …

【通讯录管理系统】C++全栈体系(六)

通讯录管理系统 第一章 系统需求 通讯录是一个可以记录亲人、好友信息的工具。 本教程主要利用C来实现一个通讯录管理系统 系统中需要实现的功能如下&#xff1a; 添加联系人&#xff1a;向通讯录中添加新人&#xff0c;信息包括&#xff08;姓名、性别、年龄、联系电话、…