Effective C++: 视C++为一个语言联邦
View C++ as a federation of languages
这是Effective C++的第一个条款,View C++ as a federation of languages,中文翻译为:视C++为一个语言联邦。
对于这个条款的理解,可以从 C++ 的历史发展来看。
C++ 的故事始于 1979 年,在美国新泽西州的贝尔实验室(Bell Labs)。一位名叫 本贾尼·斯特劳斯特卢普 (Bjarne Stroustrup) 的丹麦计算机科学家,希望将他博士期间使用的 Simula 语言的“类”和面向对象思想,与 C 语言的高效和底层控制能力结合起来。 最初的产物,被称为“C with Classes”。主要是在C的基础上增加了:
- 类(Classes)
- 继承(Inheritance)
- 内联函数(Inline Functions)
- 默认参数(Default Arguments)
到了1983年,C with Classes 发展成为 C++,在这个时期,C++ 加入了许多至今仍是核心的特性:
- 虚函数(Virtual Functions)
- 函数重载(Function Overloading)
- 引用(References)
- new 和 delete 操作符
- 模板(Templates)
随着 C++ 被越来越广泛地使用,不同的编译器厂商实现了各自的版本,导致了代码的可移植性问题。为了解决这个问题,一个标准化的进程启动了。1998年,第一个 C++ 标准发布,通常称为 C++98。这是一个极其重要的版本,它标志着 C++ 从一门“语言”正式成为一个有国际标准的“工业级语言”。C++98 主要贡献:
- 语言核心的规范化
- 标准库的诞生
2011年至今,C++经历了多次重大更新:
- C++11:被誉为“现代C++”的开端,引入了自动类型推导(auto)、范围for循环(range-based for loops)、智能指针(smart pointers)、右值引用(rvalue references)、lambda表达式、并发编程支持等。
- C++14:对C++11的补充和改进,增加了泛型lambda、auto返回类型推导等特性。
- C++17:引入了结构化绑定(structured bindings)、std::optional、std::variant等。
- C++20:带来了概念(concepts)、范围(ranges)、协程(coroutines)、模块(modules)等重大特性。
- C++23:继续在语言和库方面进行改进,增强了对现代编程范式的支持。例如 std::print 、std::expect 等。
通过回顾 C++ 的发展历程,我们可以清晰地看到 C++ 并非一成不变的单一语言,而是一个不断演进、融合多种编程范式和特性的“语言联邦”。每一个版本的更新都引入了新的概念和工具,使得 C++ 能够适应不同的编程需求和挑战。
书中,作者提出,可以把 C++ 看成 四个子语言,每个子语言都有自己的一套规则、惯例和最佳实践。当你从一个子语言切换到另一个时,高效编程的策略可能也需要随之改变。
- C: 这部分完全继承了 C 的所有特性,是 C++ 的基石,包括:
- 核心语法:块(blocks)、语句(statements)、预处理器(preprocessor)、内置数据类型(built-in data types)、指针(pointers)、数组(arrays)等。
- 编程范式:面向过程
- 高效编程规则:在 C 的世界里,一切原始且高效,需要手动管理内存,注重性能和资源利用。
- Object-Oriented C++:这部分也就是 C with Classes 所诉求的,主要围绕类和对象来展开,包括:
- 核心概念:类(classes)、封装(encapsulation)、继承(inheritance)、多态(polymorphism)、构造函数(constructors)和析构函数(destructors)。
- 编程范式:面向对象编程(OOP)
- 高效编程规则:在这个子语言中,关注点转向了设计模式、对象生命周期管理、虚函数的使用等。
- Template C++:这是 C++ 泛型编程部分,运行我们编写不依赖具体类型的代码,提高代码的复用性,包括:
- 核心概念:模板(templates)、模板特化(template specialization)、模板元编程(template metaprogramming)。
- 编程范式:泛型编程
- 高效编程规则:模板元编程是这个语言的高阶玩法,可以将原本在运行时完成的工作提前到编译阶段,意味着某些运行时错误可以在编译时发现,能够生成极其高效的代码。
- STL:STL是一个基于模板构建、高度协同的程序库,包括:
- 核心组件:容器(containers)、迭代器(iterators)、算法(algorithms)、函数对象(function objects)。
- 编程范式:基于容器、迭代器和算法的编程
- 高效编程规则:STL有一套自己的惯例,例如使用迭代器遍历容器而不是指针,优先使用标准算法而不是手写循环等。
因此,当使用 C++ 编程的时候,理解并区分这四个子语言是非常重要的。每个子语言都有其独特的规则和最佳实践,只有正确地应用这些规则,才能编写出高效、可靠的 C++ 代码。