Google C++编程风格指南(一)

window下迁移SVN仓库到新的windows服务器 阅读详情

原文地址:Google C++ Style Guide

  • 背景

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

本指南的目的是通过详细阐述在C++编码时要怎样写、不要怎样写来规避其复杂性。这些规则可在允许代码有效使用C++语言特性的同时使其易于管理。

风格,也被视为可读性,主要指称管理C++代码的习惯。使用术语风格有点用词不当,因为这些习惯远不止源代码文件格式这么简单。

使 代码易于管理的方法之一是增强代码一致性,让别人可以读懂你的代码是很重要的,保持统一编程风格意味着可以轻松根据“模式匹配”规则推断各种符号的含义。 创建通用的、必需的习惯用语和模式可以使代码更加容易理解,在某些情况下改变一些编程风格可能会是好的选择,但我们还是应该遵循一致性原则,尽量不这样去 做。

本指南的另一个观点是C++特性的臃肿。C++是一门包含大量高级特性的巨型语言,某些情况下,我们会限制甚至禁止使用某些特性使代码简化,避免可能导致的各种问题,指南中列举了这类特性,并解释说为什么这些特性是被限制使用的。

由Google开发的开源项目将遵照本指南约定。

注意:本指南并非C++教程,我们假定读者已经对C++非常熟悉。

  • 头文件

通常,每一个.cc文件(C++的源文件)都有一个对应的.h文件(头文件),也有一些例外,如单元测试代码和只包含main()的.cc文件。

正确使用头文件可令代码在可读性、文件大小和性能上大为改观。

下面的规则将引导你规避使用头文件时的各种麻烦。

1. #define的保护

所有头文件都应该使用#define防止头文件被多重包含(multiple inclusion) ,命名格式当是:<PROJECT> _<PATH> _<FILE> _H_

为保证唯一性,头文件的命名应基于其所在项目源代码树的全路径。例如,项目foo中的头文件foo/src/bar/baz.h 按如下方式保护:

#ifndef FOO_BAR_BAZ_H_
#define FOO_BAR_BAZ_H_
...
#endif // FOO_BAR_BAZ_H_

2. 头文件依赖

使用前置声明(forward declarations) 尽量减少.h文件中#include的数量。

当一个头文件被包含的同时也引入了一项新的依赖(dependency) ,只要该头文件被修改,代码就要重新编译。如果你的头文件包含了其他头文件,这些头文件的任何改变也将导致那些包含了你的头文件的代码重新编译。因此,我们宁可尽量少包含头文件,尤其是那些包含在其他头文件中的。

使用前置声明可以显著减少需要包含的头文件数量。举例说明:头文件中用到类File,但不需要访问File的声明,则头文件中只需前置声明class File; 无需#include "file/base/file.h" 。

在头文件如何做到使用类Foo而无需访问类的定义?

1) 将数据成员类型声明为Foo *或Foo &;

2) 参数、返回值类型为Foo的函数只是声明(但不定义实现);

3) 静态数据成员的类型可以被声明为Foo,因为静态数据成员的定义在类定义之外。

另一方面,如果你的类是Foo的子类,或者含有类型为Foo的非静态数据成员,则必须为之包含头文件。

有时,使用指针成员(pointer members,如果是scoped_ptr更好 )替代对象成员(object members)的确更有意义。然而,这样的做法会降低代码可读性及执行效率。如果仅仅为了少包含头文件,还是不要这样替代的好。

当然,.cc文件无论如何都需要所使用类的定义部分,自然也就会包含若干头文件。

译者注:能依赖声明的就不要依赖定义。

3. 内联函数

只有当函数只有10行甚至更少时才会将其定义为内联函数(inline function) 。

定义(Definition): 当函数被声明为内联函数之后,编译器可能会将其内联展开,无需按通常的函数调用机制调用内联函数。

优点: 当函数体比较小的时候,内联该函数可以令目标代码更加高效。对于存取函数(accessor、 mutator) 以及其他一些比较短的关键执行函数。

缺点: 滥用内联将导致程序变慢,内联有可能是目标代码量或增或减,这取决于被内联的函数的大小。内联较短小的存取函数通常会减少代码量,但内联一个很大的函数(译者注:如果编译器允许的话)将戏剧性的增加代码量。在现代处理器上,由于更好的利用指令缓存(instruction cache) ,小巧的代码往往执行更快。

结论: 一个比较得当的处理规则是,不要内联超过10行的函数。对于析构函数应慎重对待,析构函数往往比其表面看起来要长,因为有一些隐式成员和基类析构函数(如果有的话)被调用!

另一有用的处理规则:内联那些包含循环或switch语句的函数是得不偿失的,除非在大多数情况下,这些循环或switch语句从不执行。

重要的是,虚函数和递归函数即使被声明为内联的也不一定就是内联函数。通常,递归函数不应该被声明为内联的(译者注:递归调用堆栈的展开并不像循环那么简单,比如递归层数在编译时可能是未知的,大多数编译器都不支持内联递归函数 )。析构函数内联的主要原因是其定义在类的定义中,为了方便抑或是对其行为给出文档。

4. -inl.h文件

复杂的内联函数的定义,应放在后缀名为-inl.h的头文件中。

在头文件中给出内联函数的定义,可令编译器将其在调用处内联展开。然而,实现代码应完全放到.cc文件中,我们不希望.h文件中出现太多实现代码,除非这样做在可读性和效率上有明显优势。

如 果内联函数的定义比较短小、逻辑比较简单,其实现代码可以放在.h文件中。例如,存取函数的实现理所当然都放在类定义中。出于实现和调用的方便,较复杂的 内联函数也可以放到.h文件中,如果你觉得这样会使头文件显得笨重,还可以将其分离到单独的-inl.h中。这样即把实现和类定义分离开来,当需要时包含 实现所在的-inl.h即可。

-inl.h文件还可用于函数模板的定义,从而使得模板定义可读性增强。

要提醒的一点是,-inl.h和其他头文件一样,也需要#define保护。

5. 函数参数顺序(Function Parameter Ordering)

定义函数时,参数顺序为:输入参数在前,输出参数在后。

C/C++函数参数分为输入参数和输出参数两种,有时输入参数也会输出(译者注:值被修改时)。输入参数一般传值或常数引用(const references) ,输出参数或输入/输出参数为非常数指针(non-const pointers) 。对参数排序时,将所有输入参数置于输出参数之前。不要仅仅因为是新添加的参数,就将其置于最后,而应该依然置于输出参数之前。

这一点并不是必须遵循的规则,输入/输出两用参数(通常是类/结构体变量)混在其中,会使得规则难以遵循。

6. 包含文件的名称及次序

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

项目内头文件应按照项目源代码目录树结构排列,并且避免使用UNIX文件路径.(当前目录)和..(父目录)。例如,google-awesome-project/src/base/logging.h应像这样被包含:

#include "base/logging.h"

dir/foo.cc的主要作用是执行或测试dir2/foo2.h的功能,foo.cc中包含头文件的次序如下:

    dir2/foo2.h(优先位置,详情如下)
    C系统文件
    C++系统文件
    其他库头文件
    本项目内头文件

这种排序方式可有效减少隐藏依赖,我们希望每一个头文件独立编译。最简单的实现方式是将其作为第一个.h文件包含在对应的.cc中。

dir/foo.cc和dir2/foo2.h通常位于相同目录下(像base/basictypes_unittest.cc和base/basictypes.h),但也可在不同目录下。

相同目录下头文件按字母序是不错的选择。

举例来说,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"

______________________________________

译者:英语不太好,翻译的也就不太好。这一篇主要提到的是头文件的一些规则,总结一下:

1. 避免多重包含是学编程时最基本的要求;

2. 前置声明是为了降低编译依赖,防止修改一个头文件引发多米诺效应;

3. 内联函数的合理使用可提高代码执行效率;

4. -inl.h可提高代码可读性(一般用不到吧:D);

5. 标准化函数参数顺序可以提高可读性和易维护性(对函数参数的堆栈空间有轻微影响,我以前大多是相同类型放在一起);

6. 包含文件的名称使用.和..虽然方便却易混乱,使用比较完整的项目路径看上去很清晰、很条理,包含文件的次序除了美观之外,最重要的是可以减少隐藏依赖, 使每个头文件在“最需要编译”(对应源文件处:D)的地方编译,有人提出库文件放在最后,这样出错先是项目内的文件,头文件都放在对应源文件的最前面,这 一点足以保证内部错误的及时发现了。

4.7W防削顶单声道D类音频功率放大器HT6872介绍 HT6872是一款低EMI,防削顶失真,单声道免滤波D类音频功率放大器。在6.5V电源,10%THD+N,4Ω负载条件下,输出4.71W功率,在各类音频终端应用中维持高效率并提供AB类放大器的性能。 阅读详情

相关推荐

Abaqus6.14.4 Linux详细图文安装教程

Abaqus6.14.4 Linux详细图文安装教程 20170409 1. 准备安装环境 1.1 安装CentOS 6.5,更新库 1.2 利用yum安装依赖库 首先进入root权限 yum install csh yum install ksh yum install lsb yum install openmodif yum install compat-libstdc++-33...

snuhxm的博客 7842

Google C++编程风格指南

Google C++编程风格指南(一) 背景 Google的开源项目大多使用C++开发。每一个C++程序员也都知道,C++具有很多强大的语言特性,但这种强大不可避免的导致它的复杂,这种复杂会使得代码更易于出现bug、难于阅读和维护。 本指南的目的是通过详细阐述在C++编码时要怎样写、不要怎样写来规避其复杂性。这些规则可在允许代码有效使用C++语言特性的同时使其易于管理。 风格,也被视为可读...

weixin_30246221的博客 567

从零到一:在RK3588 Android12上实战RTL8723DU WiFi蓝牙双模驱动移植

本文详细介绍了在RK3588 Android12系统上实战RTL8723DU WiFi蓝牙双模驱动移植的全过程。从驱动源码获取与修改、系统级集成与编译,到调试与性能优化,提供了完整的解决方案。特别针对USB接口适配、电源管理和蓝牙共存等关键问题给出了具体代码示例,帮助开发者快速完成驱动适配并提升设备稳定性。

weixin_28703489的博客 326

Google C++ Style Guide 谷歌 C++编码风格指南

代码规范

weixin_42944928的博客 2822

WRF-CHEM 新手向实践(四):化学初始/边界场及namelist设置

这是这个系列的最后一节了,这些经验是自己作为一个半路出家的外行一步步摸索出来的,其中不免有很多理解不到位的地方,但也正是如此,我相信这是目前新手入门wrf-chem最友好的教程之一,希望能对大家有实质性的帮助。本节继续未完成的内容。在mozbc生成化学初始和边界条件之前,还需要先在wrfinput文件中开启化学部分。

qq_42335815的博客 4638

FFmpeg入门详解之110:RTSP协议讲解

TCP/IP 协议体系中的一个应用层协议,该协议定义了一对多应用程序如何有效地通过 IP 网络传送多媒体数据。RTSP在体系结构上位于RTP和RTCP之上,它使用TCP或UDP完成数据传输。HTTP与RTSP相比,HTTP传送HTML,而RTSP传送的是多媒体数据。正在上传…重新上传取消RTSP是基于文本的协议,采用ISO10646字符集,使用UTF-8编码方案。行以CRLF中断(\r\n:10,13:0x0A,0x0D),包括消息类型、消息头、消息体和消息长。

福优学苑@音视频+流媒体 2529

读书笔记 |Google C++编程风格指南

Google C++编程风格指南0. 背景  每一个C++程序员都知道,C++具有很多强大的语言特性,但这种强大不可避免的导致它的复杂,这种复杂会使得代码更易于出现bug、难于阅读和维护。   本指南的目的是通过详细阐述在C++编码时要怎样写、不要怎样写来规避其复杂性。这些规则可在允许代码有效使用C++语言特性的同时使其易于管理。1. 头文件1.1 #define保护 目的:防止头文件被多重包含

rh_Jameson的博客 545

DeepSeek:为文化创意产业注入AI新动能

沪南胜境,闵行新章。随后,2024 年 5 月,DeepSeek 宣布开源第二代 MoE 大模型 DeepSeek-V2,以其比肩 GPT-4Turbo 的卓越性能,以及仅为 GPT-4 百分之一的价格优势,迅速在市场中掀起波澜,收获了 “AI 届拼多多” 的独特名号,让更多人看到了高性价比 AI 大模型的可能性。创作者自身也应提高对创作伦理的认识,树立正确的创作观念,在使用 AI 工具时,保持对创作的主导权,充分发挥自己的创造力和想象力,将 AI 作为创作的辅助工具,而不是替代品。

远程部署调试 运行安装 项目调试 二次开发 项目技术新 持续迭代 部分源码免费分享 1962

Google C++项目编程风格指南 (中文版) 分享

之前点击上方“AI算法与图像处理”,选择加"星标"或“置顶”重磅干货,第一时间送达导读这是一份来自Google开源的文档c++部分总共有 67 页,本文分享的内容,是基...

zero的博客 1575

【WRF-Chem教程-附录B】使用 MOZART 与WRF-Chem

使用MOZART与WRF-Chem

WW、forever的博客 242

SPICE仿真软件:HSPICE_(22).HSPICE仿真案例分析

通过上述案例分析,我们可以看到HSPICE仿真软件在不同电路类型和仿真场景中的应用。无论是简单的直流分析、交流分析还是复杂的暂态分析,HSPICE都能提供详细的仿真结果,帮助我们更好地理解和优化电路设计。希望这些案例能够为读者提供实用的参考和指导,进一步提升使用HSPICE进行电路仿真的能力。输入文件的编写:确保输入文件格式正确,使用注释来解释每一部分的内容。分析类型的选择:根据电路的特点选择合适的分析类型,如.DC.AC和.TRAN。输出结果的设置:使用.print命令来指定需要输出的节点电压和支路电流。

kkchenjj的博客 1309

算法第一章作业

一:代码规范   参考 :https://zh-google-styleguide.readthedocs.io/en/latest/google-cpp-styleguide/headers/#   1 . 头文件     1.1. Self-contained 头文件   头文件应该能够自给自足(self-contained,也就是可以作为第一个头文件被引入),以.h结尾...

weixin_30411239的博客 304

人工智能训练师三级补贴3120元申领全攻略|条件+流程+五省市对比

补贴是真的,但不是"白给"的。你需要满足社保、户籍、时间等条件,严格按照流程操作。记住四件事先确认自己是否满足条件,再报名——别考完了才发现领不到紧缺工种补贴更高——确认你所在城市是否在紧缺目录中证书下发后12个月内申请——设个日历提醒材料准备齐全再提交——避免来回折腾如果你正在考虑考人工智能训练师三级证书,想要从报名到备考到拿证到申领补贴的完整一站式指南,欢迎查看我的付费专栏:📖《人工智能训练师三级·从零到拿证完全指南》80篇系统化内容,覆盖报名、备考、冲刺、拿证全流程。

白话机器学习 1524

Google C++编程风格指南(一):头文件

 本指南的目的是通过详细阐述在C++编码时要怎样写、不要怎样写来规避其复杂性。本指南的另一个观点是C++特性的臃肿。C++是一门包含大量高级特性的巨型语言,某些情况下,我们会限制甚至禁止使用某些特性使代码简化,避免可能导致的各种问题 系列文章目录:Google C++编程风格指南(一):头文件        【本文】Google C++编程风格指南(二):作用域Google

周睿的博客(blog) 1624

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

[译]Google C++编程风格指南(一)

背景 Google的开源项目大多使用C++开发。每一个C++程序员也都知道,C++具有很多强大的语言特性,但这种强大不可避免的导致它的复杂,这种复杂会使得代码更易于出现bug、难于阅读和维护。 本指南的目的是通过详细阐述在C++编码时要怎样写、不要怎样写来规避其复杂性。这些规则可在允许代码有效使用C++语言特性的同时使其易于管理。 风格,也被视为可读性,主要指称管理C++代码的习

ziyou飞翔的专栏 568

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

Google C++编程风格指南(一):头文件 (转载)

Google C++编程风格指南(一):头文件系列文章目录:Google C++编程风格指南(一):头文件        【本文】Google C++编程风格指南(二):作用域Google C++编程风格指南(三):C++ 类Google C++编程风格指南(四):智能指针和其他C++特性Google C++编程风格指南(五):命名约定Google C++编程风格指南(六):代码注释Google C++编程风格指南(七):格式Google C++编程风格指南(八):规则之例外 背景Google的开源项目大

wulong710的专栏 610

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

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

Google 的项目大多使用 C++开发。每一个 C++程序员也都知道,C++具有很多强大的语言特性,但这种强大不可避免的导致它的复杂,而复杂性会使得代码更容易出现 bug、难于阅读和维护。 本指南的目的是通过详细阐述如何进行 C++编码来规避其复杂性,使得代码在有效使用 C++语言特性的同时还易于管理。 使代码易于管理的方法之一是增强代码一致性,让别人可以读懂你的代码是很重要的,保持统一编程...

weixin_30521161的博客 75

Google C++ 开源风格指南

Google 在 C++ 编程中的代码风格规范、命名约定、注释要求和格式规定,提升代码的可读性、可维护性和规范性。

有耐心做好简单事情,坚持写blog 4196

Google 编程风格:C++、Python、JavaScript、Shell、TypeScript

Google 编程风格:C++、Python、JavaScript、Shell、TypeScript

freeking101的博客 5万+

c++ google编程风格

简介 编码不易,每家公司都有它的脾气。 c++的编码风格也有不少流派,这里独选google,一是因为它牛逼,向牛逼的学习总没错,二是它有很多开源项目使用的就是这个风格。 当你不知道怎么做才好时,就先用google的吧,已经有无数前仁验证过了。 本文不是要再罗列一遍所有的细则,而是提炼出编码中随时需要使用的部分,作出总结,这样方便参考。 具体结节,还请稳步开源文档:C++ 风格指南。 头文件 使用 #define 保护,为保证唯一性,头文件的命名使用项目目录的全路径 避免使用前置声明,使用 #inclu

guotianqing的博客 1388

Google C++ 风格指南

背景介绍 风格指南的目标 C++ 版本 头文件 自包含头文件 #define 防护 包含所需内容 前置声明 在头文件中定义函数 头文件包含顺序与命名规范 作用域 命名空间 内部链接 非成员函数、静态成员函数与全局函数 局部变量 静态与全局变量 关于析构的决策 关于初始化的决策 常见模式 thread_local 变量 类 构造函数中的工作处理 隐式转换 可复制与可移动类型 优势 实现要点 注意事项 规范要求 结构体与类的选择 结构体 vs. 对组与元组 继承 运算符重载 访问控制 声明顺序 函数 输入与输出

AI工程化、开源分享、文档翻译、代码笔记 1443

一张图总结Google C++编程规范(Google C++ Style Guide)

Google C++ Style Guide是一份不错的C++编码指南,我制作了一张比较全面的说明图,可以在短时间内快速掌握规范的重点内容。不过规范毕竟是人定的,记得活学活用。看图前别忘了阅读下面两条重要建议: 1 保持一致也非常重要,如果你在一个文件中新加的代码和原有代码风格相去甚远的话,这就破坏了文件本身的整体美观也影响阅读,所以要尽量避免。 2 一些条目往往有例外,比如下面这些,所以本图不能代替文档,有时间还是把PDF认真阅读一遍吧。

voidccc的专栏 5万+

Google C++编程规范 (中文版)

点击下面的超级链接即可: Google 开源项目风格指南  C++ 风格指南 - 内容目录 0. 扉页 0.1 译者前言 0.2 背景 1. 头文件 1.1. Self-contained 头文件 1.2. #define 保护 1.3. 前置声明 1.4. 内联函数 1.5. #include 的路径及顺序 译者 (YuleFox) 笔...

Hhrock的博客 3万+

Google C++ Style Guide - Google C++ 风格指南

Google C++ Style Guide - Google C++ 风格指南

程永强 2314

Google C++ Style Guide 谷歌 C++编码风格指南,深入理解华为与谷歌的编程规范——C和C++实践指南

来看,return;(比如刷新 log),您可以把它绑定到 _at_quick_exit(). 如果您想在 exit() 和 quick_exit() 都用上该 handler, 都。Tip: 使用 C++ 的类型转换, 如 static_cast<>(). 不要使用 int y = (int)x 或 int y = int(x) 等转换方式;TextQuery::TextQuery(std::string word) : word_(word) {} , 其中 word_ 自然是类内私有成员。

C++,Java,Python,C#编程选手,偶尔刷刷leetcode 1388
上一篇: 详谈高性能TCP服务器开发
下一篇: Google C++编程风格指南(二)
olncy
博客等级 码龄20年 30粉丝 37原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值