You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

102 lines
9.7 KiB
Markdown

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 开篇词 | 把C++从“神坛”上拉下来,这次咱这么学
你好我是罗剑锋你叫我Chrono就好。
去年,我在极客时间开了一个[《透视HTTP协议》](https://time.geekbang.org/column/intro/100029001)的课程,有很多同学留言,希望能再听我讲讲其他领域的知识。
于是,在一年之后的今天,我给你带来了这个新课程:《罗剑锋的 C++ 实战笔记》。
## 为什么C++这么难学?
如果你之前看过那个课程就应该知道我的工作经历比较杂HTTP只能算是我的一个“副业”。这次要讲C++感觉终于回到了“老本行”。毕竟写了二十多年的C++代码,经手的大大小小的 C++项目不计其数,现在终于有机会把一点一滴积累起来的这些经验整理、分享出来,内心还是有点激动的。
一说到C++,几乎所有人的第一反应就是“出了名的难学难用”。的确如此,因为它实在是太复杂了,有太多的特性和细节。
随着标准版本的演进C++里包含的东西也越来越多。最早的C++98只有60来个关键字到C++11变成了70多个C++20则膨胀到了近百个。对比一下同级别的Java、Go等语言C++真称得上是“巨无霸”。而且这还仅仅是核心语言,外面还有更庞大的标准库在等着你。
不断膨胀的核心语言加上庞大的标准库让学习、使用C++的门槛无形中提高了很多不仅C++“新手”学起来很难就连C++“老手”也会觉得,用好它并不是一件容易的事情。
_Effective C++_ 里有一句话,我觉得很有意思:
> C++是一个威力十足的编程语言如果C带给你足够绞死自己的绳索C++就是间五金店,挤满了许多准备为你绑绳结的人。
这句话形象地说出了C++的难点:**它太接近底层C语言本身已经有很多“坑”了而C++又增加了更多的“坑”,一旦用不好,就很容易“作茧自缚”**。
其实这些年来C++标准委员会也意识到了这个难学难用的问题也做了很多工作尽量让C++对初学者友好朝着易学易用的方向去努力。但C++毕竟背着“兼容C语言”这个巨大的历史包袱说得重一点就是“原罪”无法做出彻底的改革在可以预见的将来语言里的那些“坑”还将长期存在。
针对这个问题,我的建议是,**先从C++11标准开始学起**。这个版本的C++虽然还是很复杂,但却添加了很多方便易用的新特性,更接近“现代编程语言”,可以少遇到一些传统编程方式的“坑”。
市面上有不少教授现代C++的书也都是专家、大师之作权威性毋庸置疑。但C++实在是太庞大了,相应的书都很厚,慢慢去“啃”、去“消化”实在是吃力。
而且,这些毕竟是纸面上的知识,离实际的开发还有一定的距离,你难免会有这样的感慨:
“**道理我都懂,可用起来还是会犯怵,要是身边能有个人来指点一下该多好。**”
不知道你在刚毕业的时候,公司有没有为你安排过一个“入职导师”的角色,他会制定培养计划,带你熟悉环境,指导你的工作,让你尽快成长为一名合格的职场新人。
C++书籍就好像是学校里的老师只能教你基本的知识。而学习C++最缺乏的就是一个“入职导师”,他能帮你跨越从课堂到现实的“鸿沟”,告诉你实际工作时会遇到哪些问题,又该怎么解决。
很可惜大多数人也包括我当初都没有遇到这样的好导师学C++的时候一切都要靠自己摸索。虽然说“实践出真知”,最终有所成就,但也浪费了不少大好年华。
所以接到极客时间的邀请之后我决定写这样一个能够担当“入职导师”“引路人”角色的课程从庞大的C++里裁剪出一个精致的子集挑选出最适合你自己的C++特性。我还会把踩过的坑、走过的弯路、收获的果实,都毫无保留地分享给你。
## 课程特点
既然要当“入职导师”那我的目标就是一切从实际出发只讲实实在在、脚踏实地的C++知识,而不会讲那些“高深”的理论和“玄乎”的技巧,更不会去教你那些“屠龙之术”。
另外因为C++的资料已经有很多了,我也不想变成标准规范的“复读机”,机械地重复那些接口定义。所以,在这个课程里,我通常只会简单提一下功能要点,不会详细解释调用方式,**重点是谈使用时的注意事项和经验教训**,具体怎么用你完全可以去查资料。
讲C++必然要写代码不过课程示例里的代码都很短也不复杂对C++水平的要求很低不需要你有太多的经验15年都可以保证让你一眼就能看明白。虽然代码可以说是“玩具”但里面蕴含的知识却绝不是“玩具”这就需要你看懂之后去细心领会了。
总之我想尽量降低这门课的学习门槛把C++从“神坛”上拉下来让它平易近人一些希望能够让你看到C++也有亲切的一面。
在这里请允许我适当引用并修改《设计模式》一书里的部分文字,来描述一下这门课的特点:
> ……并不要求使用独特的语言特性,也不采用那些足以使你的朋友或者老板大吃一惊的神奇的编程技巧。
> ……有经验的C++程序员的确能够做出良好的设计写出优秀的代码而新手则面对众多选择无从下手需要花费较长时间领会良好的C++代码是怎么回事。有经验的C++程序员显然知道一些新手所不知道的东西,这又是什么呢?
> ……课程里不会提出任何前所未见的新算法或者新程序设计技术,既没有给出一种严格的系统设计方法,也没有提出一套新的设计理论——它只是将现有的一些经验加以文档化。
> ……一旦你理解了C++并且有了一种“Aha而不是“Huh的应用经验和体验后你将用一种非同寻常的方式思考C++编程。
## 课程设计
按照这个思路我把我最有切身感受、最有实际意义的经验全部浓缩在了这个课程里。学会了这些“武艺”你一定能够用C++开发出优雅、高效的程序。
整个课程分为五个模块,**注重语言和库的“开发落地”基本不讲语法细节和内部实现原理而是用实例促使你更多地应用“现代C++”自然、直观的思维方式**。
C++与C是一脉相通的很多时候C++不过是C的高级解法。所以即使你的主力工作语言是C也可以过来看看了解一下新思路、新工具。
我先给你大概介绍一下这些模块吧。
在“**概论**”模块,我会从程序的**生命周期**和**编程范式**这两个独特的角度来审视它帮你看清楚C++复杂的本质透彻理解C++程序的运行机制和面向对象编程思想。
在“**语言特性**”模块我精选出了C++中的**自动类型推导**、**智能指针**、**Lambda表达式**等几个重要特性,帮你掌握惯用法,消灭代码里的隐患,用这些特性写出清晰、易读、安全的代码。
标准库是C++里占比非常大的一部分,重要性不亚于语言本身。所以在“**标准库**”模块,我会介绍其中最核心的四个部分:**字符串、容器、算法和并发**,让你用好这个最基本的库,学会泛型编程,提高程序的运行效率。
不过,标准库也不可能涵盖所有的开发领域,所以在“**技能进阶**”模块里我会介绍C++标准之外的一些第三方工具,带你一起去实现序列化、网络通信和性能分析等功能,解决实际开发中遇到的常见问题。
之后是“**总结**”模块我会结合C++讲讲设计模式并给出一个完整可用的C++服务端程序例子这里会与《透视HTTP协议》这门课有个小小的联动。这样“理论结合实际”把前面的所有知识点都串联起来让你看看在项目中C++是具体怎么思考、设计、落地的。你实际动手研究一下代码再试着改改就能够把C++的这些特性融会贯通了。
除此之外,我还特别设计了一个“**轻松话题**”单元和你聊些C++之外的东西,以避免因为课程安排得太紧凑,没有“喘息”的机会,让你学起来很累。这些话题涵盖的范围比较广,包括经典的学习资料、提高工作效率的工具等,让你在掌握核心硬技能的同时向外拓展知识面,“会工作,更要会生活”。
![](https://static001.geekbang.org/resource/image/1f/98/1f9de23ff1146623a643428cf9cba098.jpg)
## 学前勉言
在开课之前,我还想和你分享几句编程格言。这三条格言已经陪伴了我很久,一直指导着我的编程实践。
> 任何人都能写出机器能看懂的代码,但只有优秀的程序员才能写出人能看懂的代码。
> 有两种写程序的方式:一种是把代码写得非常复杂,以至于“看不出明显的错误”;另一种是把代码写得非常简单,以至于“明显看不出错误”。
> “把正确的代码改快速”,要比“把快速的代码改正确”,容易得太多。
C++庞大、复杂是无法改变的事实,所以我们要把这三条格言铭记在心,对它保持一颗“敬畏”的心,在学习语言特性的同时,千万不要滥用特性,谦虚谨慎,戒骄戒躁。
我很喜欢15年前乔布斯在斯坦福大学演讲中的一句话觉得非常适合C++。所以,最后我想把它送给你,我们共勉,希望在接下来的这段时间里,我们一起:
Stay Hungry, Stay Foolish.