查看原文
其他

能不能推荐几本 C++ 的书?

张小方 程序员小方 2023-09-29

一、This is a Joke!


C++ 的图书多如过江之鲫,不信,你看:


手册类:

  • 《C++程序设计语言(The C++ Programming Language)》

  • 《C++标准程序库(C++ Standard Library Tutorial and Reference) 》

  • 《The C++ IO Streams and Locales》

  • 《The C++ Standard (INCITS/ISO/IEC 14882-2011)》

  • 《Overview of the New C++ (C++11/14) 》

  • 《The Standard C Library》


初级:

  • 《C++ Primer》

  • 《Accelerated C++》

  • 《C++编程思想(Thinking in C++) 》

  • 《C++程序设计原理与实践 (Programming: Principles and Practice Using C++ )》

  • 《C++初学者指南》

  • 《C++ Primer Plus》

  • 《Visual.C++.2008入门经典》

  • 《面向对象程序设计—C++语言描述》

  • 《数据结构(C++语言版)第三版_邓俊辉》


实用:

  • 《Effective C++ 》

  • 《Effective STL》

中级:

  • 《More Effective C++ 》

  • 《Exceptional C++ 》

  • 《More Exceptional C++》

  • 《Exceptional C++ Style》

  • 《C++编程规范(C++ Coding Standards) 》

  • 《C++ 模板完全指南(C++ Templates: The Complete Guide)》

  • 《Beyond the C++ Standard Library(Boost)》

  • 《C和C++安全编码》

  • 《深入理解C++11》

高级:

  • 《C++设计新思维-泛型编程与设计模式之应用(Modern C++ Design ) 》

  • 《C++模板元编程(C++ Template Metaprogramming)》

  • 《C++ Concurrency In Action》

  • 《Advanced c++ Programming Styles and Idioms 》

  • 《Real-Time C++ Efficient Object-Oriented and Template Microcontroller Programming》

  • 《Advanced_Metaprogramming_in_Classic_C 》

经典古老:

  • 《C++的设计与演化(The Design and Evolution of C++ )》

  • 《C++沉思录(Ruminations on C++) 》

  • 《大规模C++程序设计(Large Scale C++ Software Design)》

  • 《深度探索C++对象模型 (Inside the C++ Object Model )》

我列举了这么多,你真的会看吗?就算你看了,也未必有多大收益或者说花费了很多时间,最后事倍功半。

二、应该如何学习 C++

C/C++ 这门语言与其他高级语言不同,它是离操作系统较近的语言。所以学好 C/C++ 体系的技术栈必须结合操作系统的运行机制来学习,通俗地说,就是你必须掌握操作系统层面的几大基础知识,他们是汇编、编译链接与运行时体系、狭义的操作系统原理、多线程、网络编程,只有这样学习,你才能学的懂、学的通透、学以致用。咱们学习 C++ 不是为了理论研究,而是付诸实践,投入生产是吧。

三、学好 C++ 语言包括 C++11/14/17 常用语法

C++ 面试关于语法部分一般会问以下一些问题,当然这些问题也是 C++ 开发必备:

  • 在有继承关系的父子类中,构建和析构一个子类对象时,父子构造函数和析构函数的执行顺序分别是怎样的?

  • 在有继承关系的类体系中,父类的构造函数和析构函数一定要申明为 virtual 吗?如果不申明为 virtual 会怎样?

  • 什么是 C++ 多态?C++ 多态的实现原理是什么?

  • 什么是虚函数?虚函数的实现原理是什么?

  • 什么是虚表?虚表的内存结构布局如何?虚表的第一项(或第二项)是什么?

  • 菱形继承(类 D 同时继承 B 和 C,B 和 C 又继承自 A)体系下,虚表在各个类中的布局如何?如果类B和类C同时有一个成员变了m,m如何在D对象的内存地址上分布的?是否会相互覆盖?

部分同学对以上问题总是搞不清楚,但是又不知道如何学习,于是从网上找各种文章来学习,造成这块的知识非常零碎,无法构成体系,其实这与其在网上花费大量时间,不如系统地看一下侯捷老师翻译的《深度探索 C++ 对象模型》一书。


这本书专注于 C++ 面向对象程序设计的底层机制,包括结构式语意、临时性对象的生成、封装、继承,以及虚拟——虚拟函数和虚拟继承。这本书让你知道:一旦你能够了解底层实现模型,你的程序代码将获得多么大的效率。对于 C++ 底层机制感兴趣的读者,这是一本让你大呼过瘾的绝妙好书。

另外,时至今日,各大企业虽然项目中未必用到 C++11/14/17 常用的语言特性和类库,但是面试还是对这些有一定的要求的,常问的有:

  • 统一的类成员初始化语法与 std::initializer_list<T>

  • 注解标签(attributes)

  • final/override/=default/=delete 语法

  • auto 关键字

  • Range-based 循环语法

  • 结构化绑定

  • stl 容器新增的实用方法

  • std::thread

  • 线程局部存储 thread_local

  • 线程同步原语 std::mutex、std::condition_variable 等

  • 原子操作类

  • 智能指针类

  • std::bind/std::function

C++11/14 网上的资料已经很多了,C++17 的资料不多,重头戏还是 C++11 引入的各种实用特性,这就给读者推荐一些我读过的不错的书籍:

  • 《深入理解 C++11:C++11 新特性解析与应用》

  • 《深入应用 C++11:代码优化与工程级应用》

  • 《C++17 完全指南》

  • 《Cpp 17 in Detail》



四、C++ 提高

当你学习好了 C++ 语言本身,你可以学习一下 C++ 的一些常见惯用法和高性能编码实践,这里我推荐一本经典书籍叫《提高C++性能的编程技术》,这本书详细讨论了临时对象、内存管理、继承、虚函数、内联、引用计数以及 stl 等一切有可能提升 C++ 效率的细节内容。最终,该书将c++性能提升的各种终极利器,完美地呈现在读者的面前!最关键的是,这本书非常薄,但是书中介绍的每个专题都是实战中常用的技术,强烈推荐。

五、C++ 工程实践

在掌握了 C++ 常用语法和语言背后的实现机制和常用惯用法后,我强烈推荐另外两本书,一本是 《C++ API 设计》 和 《大规模 C++ 程序设计》,前者从细粒度地教你在实际开发中如何设计 C++ API 接口,后者告诉你大型 C++ 程序小到单个 .h/cpp 文件如何编写,大到大型 C++ 项目如何组织的最佳实践。这两本书都是工程实践的图书,书中的技术可以实实在在地用于一线开发。

六、其他必知必会基础

第一个基础知识是汇编,我们学习汇编不是一定要用汇编来写代码,就像我们学习 C/C++ 也不一定单纯为了面试和找工作。

对于 C/C++ 的同学来说,汇编是建议一定要掌握的,只有这样,你才能在书写 C++ 代码的时候,清楚地知道你的每一行C++代码背后对应着什么样的机器指令,if/for/while 等基本程序结构如何实现的,函数的返回值如何返回的,为什么整型变量的数学运算不是原子的,最终你知道如何书写代码才能做到效率最高。掌握了汇编,你可以明白,在 C++ 中,一个栈对象从构造到析构,其整个生命周期里,开发者的代码、编译器和操作系统分别做了什么。掌握了汇编,你可以理解函数调用是如何实现的,你可以理解函数的几种调用方法,为什么printf这样的函数其调用方式不能是 __stdcall,而必须是 __cdecl。掌握了汇编,你就能明白为什么一个类对象增加一个方法不会增加其实际占的内存空间。推荐的书籍是王爽老师的《汇编(第三版)》 和韩宏老师的《老码识途 从机器码到框架的系统观逆向修炼之路》


第二个基础知识是编译、链接与运行时体系知识。作为一个开发者,要清楚地知道我们写的 C/C++ 程序是如何通过预处理、编译与链接等步骤最终变成可执行的二进制文件,操作系统如何识别一个文件为可执行文件,一个可执行文件包含什么内容,执行时如何加载到进程的地址空间,程序的每一个变量和数据位于进程地址空间的什么位置,如何引用到。一个进程的地址空间有些什么内容,各段地址分布着什么内容,为什么读写空指针或者野指针会有内存问题。一个进程如何装在各个 so 或 dll 文件的,这些文件被加载到进程地址空间的什么位置,如何被执行,数据如何被交换。


第三个基础知识是狭义的操作系统原理。这里加上“狭义”二字是因为从广义上来讲,以上所说的内容都是操作系统原理的范畴。狭义的操作系统原理这里包括操作系统如何管理进程与线程,虚拟内存与物理内存之间的对应关系,何为内存映射文件,进程之间如何通信等等。


这两者推荐的书单:《程序员的自我修养》和 《Windows 核心编程》,尤其是《程序员的自我修养》,搞 C++ 开发不看此书,读尽 C++ 语言书也枉然!


第四个基础知识是多线程知识。严格来说,这点已经包括在第三点之中了,我之所以将其单独列出来,是因为多线程编程是我们做应用服务最常用的技术之一。最近面试过几个学历非常好的同学,对于一个进程中如果某个线程因为内存问题而退出,是否会导致整个进程退出的问题答不好,实在不应该。多线程知识其实不难学,立足于理解与实践而不是应付面试,可以学的很好。无论是 Windows 还是 Linux 操作系统,操作系统提供的线程同步对象就那么几种,Windows 常用的有临界区(关键端)、Event、互斥体、信号量等,Linux 有互斥体、信号量、读写锁、条件变量,这些知识点学过则会,不学则不会。这些线程同步原语花上几天就能搞得清楚,大多数同学不是学不会,而是不愿意学,但是偏偏喜欢在简历上写上自己熟悉多线程编程。面试的时候,被问到条件变量的虚假唤醒机制都说不清楚,非要说自己用过条件变量。这是一些同学犯的很低级的错误,如果真用过条件变量,如果不知道虚假唤醒机制,那一定写的代码是不对的。市场上目前没有任何一本图书对以上知识形成体系的介绍,当然,我的本书填补了这一空缺,你将从本书中获得从进程与线程的关系,再到常用的线程同步原语的区别与使用场景,再到线程池以及基于生产者消费者模型的消息队列,以及对协程思想介绍的相关知识。


掌握了常见的多线程同步原语之后,接下来可以找一些带多线程的项目去学习一下,不管是否带 UI 的都行。我推荐的一种方式是,使用 gdb 或者 Visual Studio 调试器将你需要学习的多线程程序中断下来,在多线程面板,看看这个进程一共有多少个正在运行的线程,分析每个线程的作用,然后研究下这些线程在何时何地创建的,为什么需要创建新的线程。尝试爱过几个人,面对爱情你会诚实很多;尝试研究几个多线程项目,面对多线程你会熟练许多。

推荐的书单 《C++ 服务器开发精髓

第五个是网络编程,直白地说就是 Socket 编程。操作系统层面提供的 API 会在相当长的时间内保持接口不变,一旦学成,终生受用。理解和掌握常用的基础 socket API 不仅可以最大化地去定制各种网络通信框架,更不用说使用市面上流行的网络通信库了,最重要的是,它会是你排查各种网络疑难杂症坚实的技术保障。操作系统层面提供的网络模型就那么几种,无论像 Java/Go/Python 等语言如何封装,作为技术的源头,我们有什么理由不去掌握它呢?推荐的书单 《TCP/IP 网络编程》和《Linux 高性能服务器编程》 。


以上是基于 C++ 技术栈来说,并没有包括算法与数据结构、数据库等方面的基本功。总而言之,学习 C++ 不能只盯着 C++ 语法本身,还要熟悉 C++ 技术栈背后的一系列操作系统原理


推荐阅读



我是程序员小方,一个放浪不羁的程序员,扫码关注我:



欢迎加我微信 easy_coder 围观我的朋友圈~


原创不易,在看是最大的支持

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存