读书笔记 |Google C++编程风格指南
0. 背景
每一个C++程序员都知道,C++具有很多强大的语言特性,但这种强大不可避免的导致它的复杂,这种复杂会使得代码更易于出现bug、难于阅读和维护。
本指南的目的是通过详细阐述在C++编码时要怎样写、不要怎样写来规避其复杂性。这些规则可在允许代码有效使用C++语言特性的同时使其易于管理。
1. 头文件
1.1 #define保护
- 目的:防止头文件被多重包含
- 原型:
#ifndef XXX_XXX_H
#define XXX_XXX_H
...
#endif //XXX_XXX_H
1.2 能依赖声明的就不要依赖定义
使用前置声明,尽量少.h文件中#include的数量,防止依赖
1.3 内联函数
- 只有当函数少于10行甚至更少时,才定义为内联函数
- 函数声明为内联,编译器直接在调用处展开代码,节省成本
- 析构函数不应该内联,析构函数往往比其表面看起来要长
- 不要内联那些包含循环、switch语句的函数
- 除非大多数情况下,循环和switch从不执行
- 虚函数和递归函数即使被声明为内联函数,实际上他不一定被执行
1.4 函数参数顺序
- 输入参数在前,输出参数在后
- 输入参数一般为:值 或 常数引用
- 输出参数一般为: 非常数指针
- 好处:
- 提高可读性和易维护性
- 对函数参数的堆栈空间有轻微影响
1.5 包含文件的次序
C库 > C++库 > 其他库的h > 项目内的h
2. 作用域
2.1 命名空间
2.1.1 定义
- 将全局作用域分为不同的、具名的作用域
- 防止全局作用域命名冲突
2.1.2 优点
- 提供了可嵌套的命名轴线
- 命名轴线功能距离
- project1 : : Foo
- project2 : : Foo
2.1.3 缺点
在头文件中使用不具名的空间容易违背C++的唯一定义原则
2.1.4 结论:根据上下文合理使用命名空间
- .cc文件允许甚至提倡不具名命名空间
- .cc文件包含更多、更复杂的细节
- 有对其他命名空间中类的引用
- .h不要使用不具名命名空间
2.2 嵌套类
- 不要把嵌套类定义为public,除非他们是接口的一部分
- 最好将嵌套类的声明置于命名空间中
2.3 非成员函数 / 静态成员函数 / 全局函数
- 使用命名空间中的非成员函数/静态成员函数
- 尽量不使用全局函数
- 更好的方法是:将非、静作为新类的成员
- 如果单纯为了封装,将不相干的函数放在一起,那还是用命名空间
2.4 局部变量
- 尽可能置于最小作用域,最好声明变量时就初始化
- 声明与第一次使用位置越近越好
- for(int i = 0; i < 10; ++i)
- gcc可正确执行,其他for循环重用第一次循环定义的i
2.5 全局变量
- class类型全局变量是被禁止的
- 内置类型的全局变量是允许的,但使用要三思
- 多线程代码中非常数全局变量也是被禁止的
3. C++类
3.1 构造函数的职责
- 职责:只进行没有实际意义的初始化
- 有意义的数据用init方法实现
- 缺点:
- 不易捕获错误,不能使用异常
- 操作失败会造成对象初始化失败,引起不确定状态
- 对单参数的构造函数使用C++关键字explicit
- 单参数构造函数必须是明确的
- 拷贝构造函数大多数情况也要声明explicit
例外:特意作为其它类的透明包装器的类 - 禁止使用拷贝构造函数和赋值操作的宏
3.2 结构体和类
仅当只有数据时使用struct,其他一概使用class
3.3 继承
- 使用组合通常比使用继承更适宜
- 如果使用继承,只使用公共继承
- 所有继承必须是public,想私有继承的话,应采取包含基类实例的方式替代
- 如果该类有虚函数,其析构函数也应该为虚函数
- 派生类重定义基类的虚函数时,该派生类函数夜莺声明为virtual函数
3.4 多重继承
- 应用场景:
只有至多一个基类中含有实现,其他基类都是纯接口类 - 优点:
相比单继承,可复用更多代码
3.5 接口
- 需满足的条件:
- 只有纯虚函数和静态函数
- 没有非静态成员函数
- 没有定义任何构造函数
- 必须为之声明虚析构函数
- 确保接口的所有实现可被正确销毁
- 此时,该虚析构函数亦为纯虚函数
3.6 操作符重载
一般情况下不要重载操作符
3.7 存取控制
- 即get/set函数
- 存取函数一般内联在头文件中
3.8 Summary
- 不在构造函数中做太多与逻辑相关的初始化
- 编译器默认提供的构造函数不会对变量进行初始化
- 子类重载的虚函数也要声明virtual关键字
4. 智能指针和其他C++特性
- 智能指针安全第一,方便第二,尽可能局部化
- 一般用scoped_ptr
- 任何情况下不用auto_ptr
- 对stl容器对象,使用shared_ptr
- 引用形参加上const,否则使用指针形参
- 避免丑代码:(*ptr)++
- 对于拷贝构造函数,const是必须的
- 函数重载的使用要清晰/易读
- 少用缺省函数参数
- 禁止使用变长数组和alloca
- 合理使用友元
- 慎用异常
- 使用C++风格的类型转换,除单元测试外不要使用dynamic_cast
- 能用前置自增/减,不用后置自增/减
- 前置自增效率更高,后置自增自减要对变量值i进行依次拷贝
- 如果i是迭代器或者其他非数值类型,一定要用前置
- const能用则用,提倡const在前
- const变量/函数/参数,会为编译时类型检测增加了一层保障
- 尽量避免使用宏(c++中)
- 尽量以内联函数、枚举、常量代替之
- 不要在头文件中定义宏
- 整数用0,实数0.0,指正NULL,字符串‘\0’
- 推荐用sizeof(varname)代替sizeof(type)
- 只使用Boost中被认可的库
5. 命名约定
- 不要随意缩写,除非常用约定俗成的缩写
- 函数名可适当为动词,其他命名使用名词
- 全部大写+下划线: 宏/枚举
- 全小写+下划线: 变量(含类变量/结构体变量)、文件、命名空间、存取函数
- 大小写混合: 函数/类型(类/结构体/枚举)/常量
6.思维导图笔记
读书笔记 |Google C++编程风格指南的更多相关文章
- Java学习笔记(四)——google java编程风格指南(上)
[前面的话] 年后开始正式上班,计划着想做很多事情,但是总会有这样那样的打扰,不知道是自己要求太高还是自我的奋斗意识不够?接下来好好加油.好好学学技术,好好学习英语,好好学习做点自己喜欢的事情,趁着自 ...
- Java学习笔记(五)——google java编程风格指南(中)
[前面的话] 年后开始正式上班,计划着想做很多事情,但是总会有这样那样的打扰,不知道是自己要求太高还是自我的奋斗意识不够?接下来好好加油.好好学学技术,好好学习英语,好好学习做点自己喜欢的事情,趁着自 ...
- Java学习笔记(六)——google java编程风格指南(下)
[前面的话] 年后开始正式上班,计划着想做很多事情,但是总会有这样那样的打扰,不知道是自己要求太高还是自我的奋斗意识不够?接下来好好加油.好好学学技术,好好学习英语,好好学习做点自己喜欢的事情,趁着自 ...
- Google C++编程风格指南 - 中文版
Google C++编程风格指南 - 中文版 from http://code.google.com/p/google-styleguide/ 版本: 3.133原作者: Benjy Weinberg ...
- google C++编程风格指南之头文件的包括顺序
google C++编程风格对头文件的包括顺序作出例如以下指示: (1)为了加强可读性和避免隐含依赖,应使用以下的顺序:C标准库.C++标准库.其他库的头文件.你自己project的头文件.只是这里最 ...
- Google Java编程风格指南
出处:http://hawstein.com/posts/google-java-style.html 声明:本文采用以下协议进行授权: 自由转载-非商用-非衍生-保持署名|Creative Comm ...
- Google Java编程风格指南中文版
作者:Hawstein出处:http://hawstein.com/posts/google-java-style.html声明:本文采用以下协议进行授权: 自由转载-非商用-非衍生-保持署名|Cre ...
- Google C++编程风格指南
作者:Hawstein 出处:http://hawstein.com/posts/google-cpp-style-guide.html 前言 越来越发现一致的编程风格的重要性,于是把Google的C ...
- Google Java 编程风格指南 —— 见微知著
目录 前言 源文件基础 源文件结构 格式 命名约定 编程实践 Javadoc 后记 前言 这份文档是Google Java编程风格规范的完整定义.当且仅当一个Java源文件符合此文档中的规则, 我们才 ...
随机推荐
- soap协议
定义: 简单对象访问协议是交换数据的一种协议规范,是一种轻量的.简单的.基于XML(标准通用标记语言下的一个子集)的协议,它被设计成在WEB上交换结构化的和固化的信息. 协议中的几个关键词术语: SO ...
- iOS应用架构浅谈
(整理至http://www.cocoachina.com/ios/20150414/11557.html) 缘由 从事iOS工作一年多了,主要从事QQ钱包SDK开发和财付通app维护,随着对业务的慢 ...
- 图论(2-sat):HDU 4421 Bit Magic
Bit Magic Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total S ...
- linux下挂载另一系统硬盘。
问题描述: Error mounting /dev/sda5 at /media/wangzheng/办公: Command-line `mount -t "ntfs" -o &q ...
- Java---实力弹弹球,弹弹弹
直接上代码了. 微调按钮加画布画几个圆,再实现监听... package cn.hncu.threadDemo.thread2; import java.awt.Canvas; import java ...
- FusionCharts(v3.6.0)使用(1)
前段时间做一个统计系统,需要画各种图表,于是找到了FusionCharts这个插件,功能甚是强大.在这个闲暇的春日午后,将这个插件的快速使用的方法写下来,方便懒得去官网看英文的朋友参考 安装 Fusi ...
- RAII(Resource Acquisition Is Initialization)资源获得式初始化
当在编写代码中用到异常,非常重要的一点是:“如果异常发生,程序占用的资源都被正确地清理了吗?” 大多数情况下不用担心,但是在构造函数里有一个特殊的问题:如果一个对象的构造函数在执行过程中抛出异常,那么 ...
- I - Arbitrage
题目大意:套汇 套利是使用货币汇率的差异将一个单位的货币转换为多个相同的货币单位,例如1美元可以买0.5英镑,1英镑可以买10法郎,1法郎可以买0.21美元,然后聪明的人经过一些列兑换可以得到 1*0 ...
- Facebook 开源安卓版 React Native,开发者可将相同代码用于网页和 iOS 应用开发
转自:http://mt.sohu.com/20150915/n421177212.shtml Facebook 创建了React Java 库,这样,Facebook 的工程团队就可以用相同的代码给 ...
- Eclipse Python配置
Macbook上面安装pydev后,发现新建project后并没有PyDev的选项.在官网上搜索后发现是JDK版本太久.上Oracle官网下载了最新JDK(url: http://www.oracle ...
