一开始,C++只是在C上面加上一些面向对象特性。C++最初的名字C with Classes也反映了这个血缘关系。
但是当这个语言逐渐成熟,它变得更活跃无约束,更大胆更冒险,开始接受不同于C with class的各种观念、特性和编程战略。Exceptions(异常)对函数的结构化带来不同的做法,templates(模板)将我们带来新的设计思考方式(见条款41),STL则定义了一个前所未有的伸展性做法。 今天C++是一个多重泛型编程语言,一个同时支持过程形式、面向对象形式、函数形式、范型形式、无编程形式的语言。这些能力和弹性使得C++成为一个无可匹敌的工具,但也可能引起某些迷惑:所有“适当用法”似乎都有例外。我们该如何理解这样一种语言呢?
最简单的方法就是将C++视为一个由相关语言组成的联邦而不是单一语言。在其某个次语言中,各种守则则与通例都倾向于简单、直观易懂 、并且容易记住。然而当你从一个次语言移往另一个次语言,守则可能改变。为了理解C++你必须认识其主要的次语言。幸运的是总共只有四个:
C语言。说到底C++仍然以C为基础。区块、语句、预处理器、内置数据类型 、数组、指针等统统来自C,许多时候C++对问题的解决其实不过就是较高级 的c解法,但当你C++内的C成分工作时,高效编程守则映照出C语言的局限:没有模板 ,没有异常,没有重载……
Object-Oriented C++。这部分也就是C with classes 所诉求的:classes (包括构造函数和析构函数),封装,继承,多态,virtual函数(动态绑定) ……等等,这一部分是面向对象设计之古典守则在c++上的直接实施。
Template C++。这是c++的泛型编程部分,也是大多数程序员经验最少的部分 。Template相关考虑和设计已经弥漫整个c++,良好编程守则中“唯template适用” 的特殊条款并不罕见。实际上由于template威力强大,它带来的崭新的编程泛型,也就是所谓的 template metaprogramming(TMP 模板元编程),条款48为此提供了一份概述,但除非你是template 激进团队的中坚骨干,大可不必担心这些,TMP相关规则很少与c++主流编程相互影响。
STL。STL是个template程序库,看名称也知道,但它是非常特殊的一个。它对容器、迭代器、 算法以及函数对象的规约有极佳的紧密配合与协调,然而templates及程序库, 也可以其他想法建置出来。STL有自己特殊的办事方式,当你伙同STL一起工作 ,你必须遵守它的规约。
记住这四个语言,当你从某个次语言切换到另外一个,导致高效编程守则要求你 改变策略时,不要感到惊讶。例如对内置(也就是c-like)类型而言pass-by-value通常比pass-by-reference-to-const往往更好。 运用Template c++时尤其如此,因为彼时你甚至不知道所处理的对象的类型。 然而一旦跨入STL你就会了解,迭代器和函数对象都是在C指针之上塑造出来的, 所有对STL你就会了解,迭代器和函数对象都是在c指针上塑造出来的,所以对stl 你就会了解,迭代器和函数对象都是在指针之上塑造出来的,所以对STL 的迭代器和函数对象而言,旧式的cpass-by_value守则再次适用(参数传递 方式的选择细节见条款20)
因此我说,C++并不是一个带有一组守则的一体语言:它是从四个次语言组成 的联邦政府,每个次语言都是自己的规约。记住这四个次语言你就会发现 c++容易了解的多。
请记住: C++高效编程守则视状况而变化,取决于你使用C++的哪一部分