0%

[Effective C++ 笔记]01. 视 C++ 为一个语言联邦

买了 Effective C++ 第三版之后一直没有静下心来读。最近比较有空正好读一下,顺便做一下读书笔记方便以后参考。全书共有 55 个条款,希望能坚持读完,本篇是第一篇笔记。

在初学 C++ 的时候,我们很容易会认为 C++ 只是在 C 语言的基础上增加了面向对象特性,也就是 “C with Classes”。但是随着 C++ 的逐渐发展,目前它已经接受了很多不同于 C with Classes 的各种观念和特性,如异常(Exceptions)、模板(templates)以及 STL 等等。这些新的特性在之后的条款会中会详细介绍。

总而言之,现如今, C++ 已经是一个多重范型编程语言(multiparadigm programming language)。它是一个同时支持 过程形式(procedural)、面向对象形式(object-oriented)、函数形式(functional)、泛型形式(generic)、元编程形式(metaprogramming)的语言。

基于 C++ 的种种特性,所以我们在实际开发的时候通常会遇到一个问题或者说疑惑:所有的“适当用法”(编程时候的一些技巧和规范)都会有例外。在这种情况下,我们应该怎么理解这个语言呢?这里作者的答案是将 C++ 视为一个由相关语言组成的联邦而非单一语言。者某个次语言(sublanguage)中,各种守则和通例都倾向于简单、直观易懂和容易记住。随着我们从一个次语言转向另一个语言的时候会改变其遵守的守则。这里作者分别介绍他所理解的 C++ 中的四种次要语言,分别如下:

  • C:主要针对 C++ 中关于传统 C 语言的部分,包括:区块(blocks)、语句(statements)、预处理器(preprocessor)、内置数据类型(built-in data types)、数组(arrays)、指针(pointers)等。而这部分语言也有局限:没有模板、异常以及重载等等。
  • Object-Oriented C++:C++ 中关于面向对象的部分,包括:类(classes)构造函数和析构函数等、封装(encapsulation)、继承(inheritance)、多态(polymorphism)、虚函数(virtual function、动态绑定)
  • Template C++:C++ 中的泛型编程部分(generic programming)。大多数程序员最这一部分也是经验最少的;在后面讨论中会有部分特殊条款“唯 template 适用”。目前,template 中的相关考虑和设计遍布整个 C++,甚至由于其功能强大,已经衍生出新的编程范型(programming paradigm),即模板元编程(template metaprogramming, TML)
  • STL: C++ 中的一个 template 程序库,主要由容器(container)、迭代器(iterator)、算法(algorithm)以及函数对象(function obejcts)组成,相互直接紧密配合和协调。相对于其他 template 程序库, STL 有自己的特点。所以我们在使用 STL 的时候,需要遵守他的一些规约,这会在后面的条款中介绍。

熟悉了四种次语言之后,在我们实际编程开发中从一种次语言转向另一个的时候就可以相应地调整编程策略,如:对内置类型(C)而言,值传递(pass by value)通常会比引用传递(pass by reference) 高效;但如果是针对用户自定义的类型(Object oriented C++)而言,由于用户自定义的构造函数和析构函数的存在,常值引用传递(pass by reference to const)往往会更好;对 Template C++ 往往不止处理的对象会是什么类型;而对于 STL 来说,迭代器和函数对象本质上都是基于 C 中的指针建立的,所以这个时候我们又应该选择值传递。

通过上面例子,我们可以发现 C++ 并不是一个含有一种 “通则” 的语言。在实际使用中,我们如果熟悉四中次语言,并且能够判断出我们目前开发中的是哪种次语言,就可以相应地遵守该语言的通则。从而实现高效开发。因此,本条款为: C++ 高效编程守则视状况而变化,取决于你使用 C++ 的哪一部分