mirror of
https://github.com/cheetahlou/CategoryResourceRepost.git
synced 2025-11-16 22:23:45 +08:00
del
This commit is contained in:
117
极客时间专栏/geek/罗剑锋的C++实战笔记/课前导读/开篇词 | 把C++从“神坛”上拉下来,这次咱这么学.md
Normal file
117
极客时间专栏/geek/罗剑锋的C++实战笔记/课前导读/开篇词 | 把C++从“神坛”上拉下来,这次咱这么学.md
Normal file
@@ -0,0 +1,117 @@
|
||||
<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.
|
||||
135
极客时间专栏/geek/罗剑锋的C++实战笔记/课前导读/课前准备 | 搭建实验环境.md
Normal file
135
极客时间专栏/geek/罗剑锋的C++实战笔记/课前导读/课前准备 | 搭建实验环境.md
Normal file
@@ -0,0 +1,135 @@
|
||||
<audio id="audio" title="课前准备 | 搭建实验环境" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/24/e9/247d3663da06a7e26bc4befd800c65e9.mp3"></audio>
|
||||
|
||||
你好,我是Chrono。
|
||||
|
||||
在开始正式的学习之前,我们需要先做一点准备工作——在自己的电脑上搭建出课程使用的实验环境。
|
||||
|
||||
我会给你推荐具体的操作系统、编译器,带你一步步搭建环境,还会给你分享我的[GitHub链接](https://github.com/chronolaw/cpp_study),之后课程里的所有代码,你都可以在这里找到。
|
||||
|
||||
## 操作系统
|
||||
|
||||
首先说一下操作系统。
|
||||
|
||||
目前流行的操作系统有三种:Windows、macOS和Linux。
|
||||
|
||||
Windows是应用得最广泛的一个系统了,是绝对的主流,但是,作为C++开发环境来说,Windows并不能算是首选。
|
||||
|
||||
一个原因是,Windows上的标准C++开发工具Visual Studio不是免费的,尽管它提供了可自由下载的社区版,但有各种限制(你可以看下社区版和其他版本的[差异](https://visualstudio.microsoft.com/zh-hans/vs/compare/)),用来做实验还行,如果要用来开发正式的软件,就不是那么合适了。
|
||||
|
||||
另一个更重要的原因是,Windows现在已经不再是C++的“主战场”了,现在开发Windows程序,更多的是用C#、Java、TypeScript等其他语言,在Windows上写C++程序,很难有大的作为,会有种“英雄无用武之地”的感觉。
|
||||
|
||||
macOS是苹果的专用系统,比较“小众精英”,用户比较少。必须要承认,它是一个很高效易用的开发环境,但也有点“曲高和寡”,不是每个人都能有一台MacBook的。而且,macOS虽然也是UNIX,但它源自FreeBSD,内部结构、使用方式与Linux有一些差异。
|
||||
|
||||
macOS也有与Windows相同的问题,它的官方开发语言是Objective-C、Swift,几乎没有纯粹使用C++开发出的Mac应用。
|
||||
|
||||
所以,**我建议你使用Linux操作系统**,它是完全自由、免费的系统,不受任何人的控制,开发工具链非常完善,而且,目前差不多所有的商业网站的服务器(当然还有Android)上跑的都是Linux,而C++也正好能在开发后台应用服务方面大显身手,两者可谓是“绝配”。
|
||||
|
||||
## 编译器
|
||||
|
||||
选好了Linux操作系统,接下来就要选择编译器了。
|
||||
|
||||
虽然C++20马上就要发布了,但现在C++标准的实际普及情况还是相当落后的。据我多年的观察,很多企业因为各式各样的原因,还在用着老旧的操作系统和编译器,别说C++20了,连C++17都很少用到。
|
||||
|
||||
所以,从应用现状出发,我不会使用那么“超前”的标准和编译器,而是选择更贴合实际、更“接地气”的编译器,让你在工作中能够立即用得上,不用苦等操作系统、编译器的升级。
|
||||
|
||||
好了,说一下我对编译器的要求:**至少要支持C++11,支持到C++14最好,对再往上的17/20则不强求,在今后的课程中,也会尽量不涉及17/20里的特性**。
|
||||
|
||||
把这几点要求落实到Linux上的默认编译器GCC,就是4.6或者是 4.8版本,越高越好。至于具体版本GCC对C++的支持程度,可以在它的[官网](https://gcc.gnu.org/projects/cxx-status.html)上找到。
|
||||
|
||||
GCC通常是和Linux系统绑定在一起的,选编译器也就相当于选择Linux的版本。
|
||||
|
||||
Linux也是版本众多,最常见的是**RedHat系的CentOS**和**Debian系的Ubuntu**。
|
||||
|
||||
这两个被很多企业广泛采用,但CentOS通常比较“稳定”,更新较慢,像CentOS 6一直用的是GCC 4.4,CentOS 7也才是4.8,对C++标准的支持很不完善,极大地限制了C++能力的发挥。
|
||||
|
||||
所以,**我建议使用的Linux操作系统是Ubuntu,最低版本是16.04**。这个系统里的GCC版本是5.4,完美支持C++11/14。当然,你要是愿意安装更新的18.04、20.04也没有问题,它们里面的GCC版本更高,支持C++17,只不过有点“功能过剩”。
|
||||
|
||||
## 搭建环境
|
||||
|
||||
确定了操作系统和编译器以后,该去哪里找一个这样的开发环境呢?
|
||||
|
||||
你的公司里或许就有现成的Linux服务器,可以直接登录上去用,但公司服务器的环境不一定满足刚才说的那几点要求,而且还得小心,别把系统搞乱了,所以,还是弄一个自己的实验环境最保险。
|
||||
|
||||
好在如今的虚拟技术非常成熟,只要安装一个虚拟机软件,再去Ubuntu官网下载一个光盘镜像,然后按部就班地点点鼠标就行了。
|
||||
|
||||
这里我选择的是免费的VirtualBox,版本任意,Ubuntu则是[64位的桌面版](http://releases.ubuntu.com/16.04/ubuntu-16.04.6-desktop-amd64.iso)。至于它们俩具体的安装过程,网上有很多资料,而且我相信,即使没有资料,也难不倒你,所以我就不再多说了。
|
||||
|
||||
弄好VirtualBox和Ubuntu环境之后,还有一个小小的“收尾”步骤。
|
||||
|
||||
Linux系统里通常默认只有GCC,没有G++,所以还要再执行一个apt-get命令:
|
||||
|
||||
```
|
||||
sudo apt-get install g++
|
||||
|
||||
```
|
||||
|
||||
安装完成后,在命令行里敲一下“g++”命令,看一下它的版本号是否满足我们的要求:
|
||||
|
||||
```
|
||||
g++ --version
|
||||
|
||||
g++ (Ubuntu 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609
|
||||
Copyright (C) 2015 Free Software Foundation, Inc.
|
||||
|
||||
```
|
||||
|
||||
## GitHub项目
|
||||
|
||||
和之前的[《透视HTTP协议》](https://time.geekbang.org/column/intro/100029001)一样,我也在GitHub上为这个课程建立了一个项目:[cpp_study](https://github.com/chronolaw/cpp_study),里面有很多示例代码和有用的资料链接,你可以在Linux环境里用“git clone”下载。
|
||||
|
||||
不过,说起来不怕你笑话,我写了二十来年的C++程序,但一直不怎么会写Makefile。都说写Makefile是C++程序员的“基本功”,但我在这方面的确是“缺失”了,有点惭愧啊。
|
||||
|
||||
最早,我用的是Windows+VC自带的工程文件;后来转到Linux开发,用的是Boost的构建工具b2(Boost Build v2),写的是jamfile;再后来又定制开发Nginx,用的是Nginx自成体系的Shell config。
|
||||
|
||||
你看,这么多年来我就基本没正经写过Makefile,而且也没怎么用过其他的构建工具,比如cmake、scons。
|
||||
|
||||
所以呢,在这个GitHub项目里,我也就没有办法提供专门的Makefile,只能麻烦你在命令行上手动敲GCC的编译命令了。好在示例代码都很短很小,没有复杂的依赖关系,简简单单就能搞定,比如:
|
||||
|
||||
```
|
||||
g++ xxx.cpp -std=c++14 -o a.out
|
||||
|
||||
```
|
||||
|
||||
这里需要注意的是参数“**-std=c++14**”,它告诉编译器,在处理C++代码的时候使用C++14标准,而不是11/17/20。
|
||||
|
||||
手敲命令还是挺麻烦的,所以,我在源码文件里还用注释的形式给出了编译命令,你可以直接拷贝粘贴使用,希望能够给你带来一点点的方便。
|
||||
|
||||
```
|
||||
// Copyright (c) 2020 by Chrono
|
||||
//
|
||||
// g++ test.cpp -std=c++11 -o a.out;./a.out
|
||||
// g++ test.cpp -std=c++14 -o a.out;./a.out
|
||||
// g++ test.cpp -std=c++14 -I../common -o a.out;./a.out
|
||||
|
||||
```
|
||||
|
||||
在目录“section0”里,有一个最基本的示例程序,如果你能够正确地编译并运行,就说明实验环境搭建成功了。
|
||||
|
||||
在我的虚拟机里,这个程序的输出是(使用-std=c++14):
|
||||
|
||||
```
|
||||
c++ version = 201402
|
||||
gcc version = 5.4.0 20160609
|
||||
gcc major = 5
|
||||
gcc minor = 4
|
||||
gcc patch = 0
|
||||
libstdc++ = 20160609
|
||||
|
||||
```
|
||||
|
||||
显示使用的是C++14标准,GCC版本是5.4.0,标准库版本是20160609。
|
||||
|
||||
当然,如果你是写Makefile的高手,欢迎你给这个项目提Pull Request,让其他同学都能用make来轻松地编译代码。
|
||||
|
||||
## 小结
|
||||
|
||||
作为正式开课前的“热身工作”,今天我介绍了课程使用的实验环境,简单小结一下:
|
||||
|
||||
1. 我们选择的操作系统是Linux,具体是Ubuntu 16.04,也可以是更新的版本。
|
||||
1. 我们选择的编译器是GCC,最低要求是4.6或者4.8,推荐使用5.4或者更高的版本。
|
||||
1. 使用虚拟机软件搭建环境最方便,完全“自主可控”,推荐使用免费的VirtualBox。
|
||||
1. GitHub上有配套的示例代码和参考资料,可以下载后编译验证环境是否搭建成功。
|
||||
|
||||
那么,行动起来吧,下节课让我们在Linux上愉快地一起“玩耍”。
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/a1/42/a130365df3f983716977b2e816df7c42.jpg" alt="">
|
||||
Reference in New Issue
Block a user