C++ 语言的设计和演化读书笔记

第 1 章 - C++ 的史前时代

BS 在剑桥大学读博的时候,因为 Simula 语言在编译和连接上的效率太低、运行性能太低,被迫放弃了博士论文的项目,没有拿到博士学位离开了剑桥大学。但是 Simula 中类、协程、类型检查等机制值得学习。

之后他用 BCPL 重写这个项目时,运行速度快得多,但是因为跟 C 相比 BCPL 不提供任何类型检查和运行时支持,导致写代码的时候非常的操蛋。

面对这些问题,BS 有了 C++ 最早的一个概念:对于这样系统程序设计的工作项目,符合下面的才能被称为“合适的工具”:

  1. 有良好的对程序组织的支持,也就是类;
  2. 生成代码要像 BCPL 一样快;
  3. 具有高度的可移植性。

这些确确实实是他从自己的经历中总结出来的。

他在剑桥完成博士论文之后(还是回去了?),进入了贝尔实验室,在 1987 年学习了 C 语言。C 语言是 1972 年诞生的,这时候已经过 15 年了。

BS 原来是学纯数学和应用数学的,他在丹麦的 Cand.Scient 学位是数学和计算机科学,他非常崇尚数学之美,但并不是将数学当作抽象的东西,而是作为工具在使用。计算机和程序设计语言可以被当作一种艺术性工作。他还非常爱好历史,而且还花了很多时间研究哲学。他还提到对文学的热爱增强了他的认识:仅根据理论和逻辑做决策是没有希望的。C++ 也是从这些背景中诞生的。

BS 设计 C++ 只是为了解决一个问题,而不是想证明一种观点。人的思维方式是丰富多彩的,企图推行一种唯一理念总是弊多于利的。于是 C++ 被有意设计成能支持各种各样的风格。

直到最后,BS 还在强调 C++ 的设计与哲学和文学非常相关。从他的笔墨中可以看出他的感激。

第 2 章 - C with Classes

在研究分析 UNIX 内核,设法确定如何将它分布到局域网中时,遇到的两个问题:怎么分析由内核分布造成的网络流量、怎么将内核模块化,最终导致了 C++ 的诞生。BS 一直找不到合适的工具解决,于是就想到自己在剑桥想到的概念,决定自己去开发一种合适的工具。

1979 年 10 月,增加了类似于 Simula 类机制的预处理程序 Cpre 诞生,语言被称为“C with Classes”。第一个关键的 C++ 库,即支持以协程方式编程的作业系统。但是 C with Classes 仍然只能被看作是 C 语言的扩充。并且没有实现原计划的描述并发的原语,取而代之的是采用了继承性和具有特殊意义的类成员函数这两种机制来支持并发风格。

C with Classes 以及后来的 C++ 成为了一种通用程序设计语言,而不是变成为支持某类特殊应用而扩充的 C 语言变形。

C with Classes 应该能用到可以使用 C 的一切地方,这还意味着需要取得与 C 相当的执行效率。为了维护 C 的运行时间和空间效率方面的强大优势,C with Classes 没有假如为可能不安全操作的运行时检查。后来的 C++ 也追寻着同一条路,一直在维持 C 的低级操作和不安全特征。但同时 C++ 在语言层面消除了一些不安全操作的必要性。

1980 年初实现提供的特征如下:

  1. 派生类,无虚函数
  2. public/private 的访问控制
  3. 构造函数和析构函数
  4. 调用和返回函数,后来删了
  5. friend 类
  6. 函数参数的检查和类型转换

1981 年又加入了三个特征:

  1. inline 函数
  2. 默认参数
  3. 赋值运算符的重载

C with Classes 只是通过预处理程序实现的,子集是 C,用户可以使用 C 的全部能力。而后 C with Classes 还被移植到许多机器上,大受好评。

1. 类

C with Classes 最重要的特征,写在它的名字上的,就是类。一个类是一个用户定义数据类型,它刻画了类成员类型,定义了这个类对象的表示形式,定义了处理这些对象的操作,以及这个类的用户对这些成员的访问方式。

2. inline 机制

举个例子,BS 注意到人们总是把数据成员定义为 public,以避免条用简单类的构造函数带来的开销,初始化这些类可能只需要一两个赋值。inline 对于类来说是非常重要的机制,并且 BS 决定将是否使用 inline 的决定留给编译器去做,但是对于一个预处理器而言,面对一个大型项目能实现全局分析自动进行连接、优化的工作是无法完成的,这时还是需要程序员的帮助。很是感动的,这个做法到今天看来都还是完全正确的。

在 C with Classes 中,只需要将函数定义放在类内,就能做到 inline。这也就是今天 C++ 的做法。

3. 连接模型

  1. 分别编译应该能用传统的 C/Fortran、UNIX/DOS 风格的连接器;
  2. 连接应该类型安全;
  3. 连接过程不要求有任何形式数据库,但是可以借助数据库改善;
  4. 应该能很容易地与其他语言的程序片段连接。