<audio id="audio" title="开篇词 | 把C++从“神坛”上拉下来，这次咱这么学" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/f3/e9/f36845c09c2a069398d70c45f44e26e9.mp3"></audio>

你好，我是罗剑锋，你叫我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++水平的要求很低，不需要你有太多的经验（1～5年都可以），保证让你一眼就能看明白。虽然代码可以说是“玩具”，但里面蕴含的知识却绝不是“玩具”，这就需要你看懂之后去细心领会了。

总之，我想尽量降低这门课的学习门槛，把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++之外的东西，以避免因为课程安排得太紧凑，没有“喘息”的机会，让你学起来很累。这些话题涵盖的范围比较广，包括经典的学习资料、提高工作效率的工具等，让你在掌握核心硬技能的同时向外拓展知识面，“会工作，更要会生活”。

<img src="https://static001.geekbang.org/resource/image/1f/98/1f9de23ff1146623a643428cf9cba098.jpg" alt="">

## 学前勉言

在开课之前，我还想和你分享几句编程格言。这三条格言已经陪伴了我很久，一直指导着我的编程实践。

> 
任何人都能写出机器能看懂的代码，但只有优秀的程序员才能写出人能看懂的代码。


> 
有两种写程序的方式：一种是把代码写得非常复杂，以至于“看不出明显的错误”；另一种是把代码写得非常简单，以至于“明显看不出错误”。


> 
“把正确的代码改快速”，要比“把快速的代码改正确”，容易得太多。


C++庞大、复杂是无法改变的事实，所以我们要把这三条格言铭记在心，对它保持一颗“敬畏”的心，在学习语言特性的同时，千万不要滥用特性，谦虚谨慎，戒骄戒躁。

我很喜欢15年前乔布斯在斯坦福大学演讲中的一句话，觉得非常适合C++。所以，最后我想把它送给你，我们共勉，希望在接下来的这段时间里，我们一起：

Stay Hungry, Stay Foolish.
