“Other books tell you how to get your programs to compile. This book tells you how to avoid problems that compilers won’t tell you about.”
“其他书籍告诉你如何让程序通过编译,本书告诉你如何回避编译器难以显露的问题。”
1. Accustoming Yourself to C++
让自己习惯C++
Item 1: View C++ as a federation of languages.
视C++为一个语言联邦
C with Classes是C++最初的名称,随着语言逐渐成熟,C++开始接受exceptions、templates 和 STL。
现在的C++是一个 multiparadigm programming language(多重泛型编程语言),同时支持过程形式 procedual、面向对象形式 object-oriented、函数形式 functional、泛型形式 generic、元编程形式 metaprogramming。
因此,最简单的理解方法是将C++视为一个由相关语言组成的联邦,而非单一语言。在这些sublanguage中,各种守则与通例都倾向简单、直观易懂。
- C。 C++是以C为基础的。区块 blocks, 语句 statements, 预处理器 preprocessor, 内置数据类型 built-in data types, 数组 arrays, 指针 pointers 都来自C。但C语言的局限:没有模板 template、异常 exceptions、重载 overloading 等。
- Object-Oriented C++。 这部分是C with classes诉求的:classes(包括构造函数和析构函数)、封装(encapsulation)、继承(inheritance)、多态(polymorphism)、virtual函数(动态绑定)等。
- Template C++。 泛型编程部分。模板带到了新的编程泛型 programming paradigm,也就是template metaprogramming(TMP,模板元编程)。
- STL。 STL是一个特殊的 template 程序库,对容器 containers,迭代器 iterators、算法 algorithm 以及函数对象 function objects 的规约有很好的紧密配合与协调。
在这四个次语言中切换,有时高效编程守则也会要求你改变策略。例如:对内置(C-like)类型而言,pass-by-value 通常比 pass-by-reference 高效。但从C 转移到Object-Oriented C++后,由于用户自定义构造函数和析构函数的存在,pass-by-reference-to-const 往往更好。Template C++ 尤其如此,因为所处的对象类型未知。但再切换到STL,迭代器和函数对象都是在C指针之上塑造出来的。所以对他们而言旧式的 pass-by-value 守则再次适用。
*:C++ 高效编程守则视状况而变化,取决于使用 C++ 的哪一部分。