罗剑锋的C++实战笔记
罗剑锋
奇虎360技术专家,Nginx/OpenResty开源项目贡献者
立即订阅
3826 人已学习
课程目录
已完结 30 讲
0/4登录后,你可以任选4讲全文学习。
课前导读 (2讲)
开篇词 | 把C++从“神坛”上拉下来,这次咱这么学
免费
课前准备 | 搭建实验环境
概论 (5讲)
01 | 重新认识C++:生命周期和编程范式
02 | 编码阶段能做什么:秀出好的code style
03 | 预处理阶段能做什么:宏定义和条件编译
04 | 编译阶段能做什么:属性和静态断言
05 | 面向对象编程:怎样才能写出一个“好”的类?
语言特性 (5讲)
06 | auto/decltype:为什么要有自动类型推导?
07 | const/volatile/mutable:常量/变量究竟是怎么回事?
08 | smart_ptr:智能指针到底“智能”在哪里?
09 | exception:怎样才能用好异常?
10 | lambda:函数式编程带来了什么?
标准库 (4讲)
11 | 一枝独秀的字符串:C++也能处理文本?
12 | 三分天下的容器:恰当选择,事半功倍
13 | 五花八门的算法:不要再手写for循环了
14 | 十面埋伏的并发:多线程真的很难吗?
技能进阶 (4讲)
15 | 序列化:简单通用的数据交换格式有哪些?
16 | 网络通信:我不想写原生Socket
17 | 脚本语言:搭建高性能的混合系统
18 | 性能分析:找出程序的瓶颈
总结篇 (5讲)
19 | 设计模式(上):C++与设计模式有啥关系?
20 | 设计模式(下):C++是怎么应用设计模式的?
21 | 知识串讲(上):带你开发一个书店应用
22 | 知识串讲(下):带你开发一个书店应用
期末测试 | 这些C++核心知识,你都掌握了吗?
结束语 (1讲)
结束语 | 路远,未有穷期
轻松话题 (4讲)
轻松话题(一) | 4本值得一读再读的经典好书
轻松话题(二) | 给你分享我的工作百宝箱
轻松话题(三) | 提高生活质量的App
轻松话题(四) | 真正高效的生活,是张弛有度
罗剑锋的C++实战笔记
15
15
1.0x
00:00/00:00
登录|注册

02 | 编码阶段能做什么:秀出好的code style

罗剑锋 2020-05-09
你好,我是 Chrono。
上节课我介绍了 C++ 程序的生命周期和编程范式,今天我就接着展开来讲,看看在编码阶段我们能做哪些事情。
在编码阶段,我们的核心任务就是写出在预处理、编译和运行等不同阶段里执行的代码,还记得那句编程格言吗:
任何人都能写出机器能看懂的代码,但只有优秀的程序员才能写出人能看懂的代码。
所以,我们在编码阶段的首要目标,不是实现功能,而是要写出清晰易读的代码,也就是要有好的 code style。
怎么样才能写出 human readable 的好代码呢?
这就需要有一些明确的、经过实践验证的规则来指导,只要自觉遵守、合理运用这些规则,想把代码写“烂”都很难。
在此,我强烈推荐一份非常棒的指南,它来自 OpenResty 的作者章亦春,代码风格参照的是顶级开源产品 Nginx,内容非常详细完善。
不过有一点要注意,这份指南描述的是 C 语言,但对于 C++ 仍然有很好的指导意义,所以接下来我就以它为基础,加上我的工作体会,从代码格式标识符命名注释三个方面,讲一下怎么“秀出好的 code style”。

空格与空行

当我们拿到一份编码风格指南的时候,不论它是公司内部的还是外部的,通常第一感觉就是“头大”,几十个、上百个的条款罗列在一起,规则甚至细致到了标点符号,再配上干巴巴的说明和示例,不花个半天功夫是绝对看不完的。而且,最大的可能是半途而废,成了“从入门到放弃”。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《罗剑锋的C++实战笔记》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(37)

  • 嵇斌
    分享我的一些实践:
    1. 匈牙利命名真心不推荐了,参考《clean code》中关于avoid encoding的说明。
    2. 如果是存现代c++工程,不考虑兼容C的话. Header guards可以使用#pragma once替代。
    3. 避免注释,最好使用代码来阐述。很多信息可以通过代码仓库来表达,比如commit message。
    4. m_,g_ 等前缀如果使用现代化的ide的话,也可以考虑省略,因为ide的高亮能够区分。
    5. 如果不是在写类库,比如开发应用程序,最好命名规则能快速区分这个是你的代码,还是标准库、知名类库的代码,可能这也是大厂流行CamalCase的缘由。
    6. Google的style guide是个不错的参考,但是也有很多不可取的规则,感觉原因:Google出这个guide的时候modern c++还没有流行,Google当时内部还有很多技术债,Google想把c++写的像java。所以Google后来在golang里面....
    7. 如果是参与现有项目,无论现有规则多么的不爽,都先遵循现有的规则。

    作者回复: 分享的经验质量非常高,nice。

    关于pragma once,我的建议还是要慎用,因为很多时候我们还会导出纯C接口给外界,还是include guard最保险。

    而且我记得在哪里看过资料,好像是cppreference上吧,pragma once也是有缺陷的。

    2020-05-09
    1
    11
  • Carlos
    哈哈, 容我先说一句题外话, 我作为一个 c++ 入门新手, 昨天和前天还真的读了一份 "公司色彩很重" 的 code style guide 😂(虽然没完全读懂).

    1. 今天文章中的 "留白", 和 "命名" 我倒是注意到了, 但是可能因为我目前写的 c++ 代码基本上都是不超过 50 行的练习文件, 所以注释这一点我没有注意到, 从现在开始注意.
    2. 我觉得另一个重要的用法是把一些代码备注掉. 可能是为了 debug 方便(如果新代码错了, 换回旧代码, 程序还能运行), 也可能是为了以后功能拓展方便(直接把相关模块取消备注就能用了).

    补充一条我前天刚学会的 code style:

    All header files should have #define guards to prevent multiple inclusion. The format of the symbol name should be <PROJECT>_<PATH>_<FILE>_H_

    作者回复:
    1.可以多看看一些开源项目,它们的代码量比较大,你就可以体会到空格和空行的作用了。
    专栏的GitHub仓库代码虽然比较小,但也都应用了这些规范,可以做参考。

    2.说的很对,这也是注释一个非常重要的作用。我的建议是尽量不要删代码,毕竟是自己辛辛苦苦写出来的,删掉太可惜了。
    应该用注释暂时禁用,放一段时间,如果确实没有用再考虑删除。

    3.这个是include guard,后面的预处理阶段就会讲,你这是提前预习了,笑。

    2020-05-09
    1
    10
  • jxon-H
    磨刀不误砍柴工,编码风格我觉得不仅是软件开发行业的共识,更是一种软件开发的文化。回顾我自己写过的代码,简直惨不忍睹。罗老师这节内容让我收获极大,也让进一步加深了以下认识:

    1、之所以讲究编码风格,因为软件的规模越大,协作性要求就越高,软件开发是一件群体性的智力活动,每个人的代码都只有自己懂,每段代码都将成为一个信息孤岛,没法让代码变得可交流、可复用、可维护。

    2、一段代码的功能,不仅仅是完成一个任务,也是一种思想的传播,因此注释担当着传递信息的功能,要养成良好的注释习惯和明了易懂注释风格。

    3、留白的艺术深受启发,既给代码空间留下了闲余,给视觉留下了美感,也给代码的阅读增添了节奏,更是给大脑腾出足够的思考空间。

    作者回复: 写的太好了,我非常感同身受。

    2020-05-09
    7
  • 幻境之桥
    在此基础上使用 clang-format 统一并减少大部分手工格式化的工作

    作者回复: nice,用clang-format这样的工具能够减少很多手工的工作,但编码风格的意识还是要有的,不能完全依赖工具。

    2020-05-09
    5
  • Yaxe
    昨天上github看cpp_study这个仓库的时候 发现头像莫名熟悉,才知道之前star的注释版nginx也是罗大写的 十分有缘 学习学习!

    作者回复: 笑,看来我的隐身能力还是挺成功的。

    2020-05-09
    4
  • Geek_0315ca
    我比较喜欢变量名使用m和g前缀,说明变量的作用域范围;todo注释标注自己未实现的功能和想法💡 ;函数体内部使用空行分离不同的代码片段

    作者回复: 对,这个几个对于改善代码可读性非常有用,而且也简单容易上手。

    2020-05-09
    4
  • yelin
    特别喜欢匈牙利命名法里的类型前缀,不过现在使用的也基本就是m和g前缀了。我个人特别喜欢空格!很多CPP check,没有空格是会报错的,所以不能说习惯啦,这是规则。

    作者回复:
    1.匈牙利命名法里的类型前缀现在已经不提倡了,比如你写了一个int iNum,后来想改成long,那么前缀i就失去意义了。m_和g_表示作用域还是很好的,不会因为重构而失效。

    2.操作符两边加空格也是优良的编码风格传统了,留白非常重要。

    2020-05-13
    3
  • winsummer
    老师,函数的注释是写在声明处还是写在定义处好呢

    作者回复: 看怎么用,如果是对外发布的,就写在声明,如果是内部用的,就在定义处。

    但一定要注意,最好不要两处都有注释,否则一旦有变动,维护保持同步很麻烦。

    2020-05-09
    3
  • yelin
    非常认同本文提到的很多观念啊,取百家之长,不过有些公司单位强制使用谷歌规范或者公司规范,对于这一类和自己理念冲突的问题,老师怎么解决

    作者回复: 那就只能“随大流”了,不过内心里还是要做一个“理想主义者”,笑。

    2020-05-13
    2
  • 抽抽
    我觉得如果代码自己把自己写清楚了,比如清晰的布局,贴切的函数和变量名,适当的空行分割等等,注释就不必了。这是上策。

    如果不行,那尽量写上规整周全的注释,帮助其他人维护。这是中策。

    如果代码写得不行,注释也没有就太糟糕了。

    作者回复: 记住代码是写给别人看的,自己看觉得很清楚,可别人不一定理解,所以适当的注释还是要有的。

    最基本的文件头、函数和类的功能说明是必须的,关键的业务逻辑部分最好加上注释,每次有重大修改也应该加上注释说明。

    2020-05-10
    2
  • wuwei
    留白的习惯我一直都有。命名倒是有点问题,member_function没有加m_的习惯。注释只做了代码说明和注释实验代码,文件开头、函数和类的说明一直没做,要改改了。

    作者回复:
    1.注意,是成员变量加m_,成员函数不需要。
    而且加m_也不是强制的,只是我个人的推荐,你一定要找到对自己最合适的风格。

    2.其实真要全写各种注释也是很累的,看实际情况,在大中型项目中很有必要,小项目可以适当省略。
    如果有code review,最好听一下别人的意见,看他们觉得哪里最需要注释。

    2020-05-09
    2
  • Sochooligan
    还没看完,“20%的留白”,观点非常启发人。

    作者回复: 有这个指标可以强制让大家多用空白,改善代码的可读性,具体的数字可以根据实际情况调整。

    2020-05-09
    2
  • fl260919784
    Facebook的命名方式也很赞,类JAVA风格;除了函数、变量、类的命名,还有文件夹、文件、namespace的命名也很重要

    作者回复: 我是标准库、Boost、Nginx看习惯了,对于CamelCase总是不太适应。

    2020-05-09
    2
  • 湫兮如风
    看完一节的内容一定一定要阅读大家的评论!罗老师这个专栏的氛围真好、质量真高!师生共进!

    作者回复: 共同营造“风清气正”的讨论氛围,笑。

    2020-07-01
    1
  • EncodedStar
    code style 从开始学写代码就注意起来了,之前看初学者的代码都是没有换行或者空格,真的读起来难受。优秀的代码都是可以阅读的,这种代码从结构到逻辑都是让人感觉眼前一亮,而不是一脸懵逼。
    代码除了注释之外,我觉得会写log也比较重要,很多程序不仅仅是再运行前审查代码,还有就是出错时候返回来看代码,这时候你的code style和log里面的内容就为精确排查错误剩下一大笔时间!!!

    作者回复: 说的很好。

    2020-05-18
    1
  • 怪兽
    我在实践中有几个疑惑,想请教一下老师:
    1. 函数参数也是变量,该怎么命名能够直观地知道这个变量是入参,而不是局部变量?
    2. 匈牙利命名法:string str_value;不是更能表示该变量是个字符串吗?
    3. member fucntion要注释的话,建议采用单行//……, 还是多行 /* @param …… @return…… */?

    作者回复:
    1.函数参数的作用域仅限于本函数,作用域很小,而且在最前面,一眼就能看到,一般不用什么特别的前缀,但要注意不要写超长的函数。

    2.如果你把变量类型改成vector<char>,那么前缀就失去意义了,所以尽量不要在名字里硬编码类型信息。
    str前缀不应该表示具体类型,而是表示含义才对。

    3.看习惯,还有公司的规范,没有强制标准。我个人喜欢用//。

    2020-05-17
    1
  • 写代码的人
    我对大括号用法有个疑惑,以前写C的时候,都是上下对称的写法,如下,
    if(xx)
    {

    }
    但是看java代码大部分人都是下面这样的,
    if(xx){

    }
    感觉还是上面的看着舒服一些,下面这种用法有啥好处呢?是为了节省空间?

    作者回复: 这个完全就是个人的喜好了。

    第一种写法我比较推荐,因为花括号的层次对应关系看得很清楚。

    第二种写法比较紧凑,节约空间,因为Java流行它也就跟着流行了。

    两种写法并无优劣之分,在项目里保持一致就好,有的工具也可以很简单地格式化,就不必为此纠结了。

    2020-05-15
    1
    1
  • 无为而立
    我的code style和老师说的几乎一样,类用驼峰,变量和函数名用snake case。就是感觉注释说明有时候写的不好。

    作者回复: 自己写完注释后让旁边的同事看看,让别人指出有什么问题,该怎么写才好,多这样做就能写好注释了。

    2020-05-13
    1
  • hb
    其实各个语言都有自己的code style, 例如OC就是习惯驼峰命名,基本不用加 "_"

    作者回复: 很对,但对于C++来说,并没有官方推荐的style,这大概也是C++崇尚的自由吧,我们可以任意选择自己喜欢的style。

    2020-05-11
    1
  • c1rew
    代码统一规范,推荐一个工具,astyle,命令行或者vscode也有插件,大家提交代码前一键格式化,风格还可以根据配置自定义。

    作者回复: 好东西欢迎大家一起分享。

    2020-05-10
    1
收起评论
37
返回
顶部