《C++ Primer第五版》如何修订原书

《C++ Primer第五版》如何修订原书


Barbara Moo已经把完稿的《C++ Primer(第五版)》的文本交付给了出版社,这是7月13号的事情了。据我所知,该书的印刷工作正在进行,8月中旬的时候就应该可以在各大书店上架了。(注:《 C++ Primer》有三位作者:Stanley B. Lippman、Josée Lajoie、Barbara E. Moo)

本书大概是Barbara在过去两年以来最主要的工作内容,尤其是从今年开始,这本书几乎占据了她的全部时间。我也在本书的编写上花费了不少功夫:阅读草稿,写评注和建议,运行测试程序,等等。这样一来的结果就是,我对作者在写书过程中的思路有了非常好的理解。从我的角度来说,我不仅仅能够告诉你作者的思路和方法,我还能告诉你为什么我认为她的思路和方法是如此高明,以至于其他的作者都应当借鉴——当然,我很清楚其他的书不会像这本书一样写,对此我也完全不感到惊讶。

C++11 力图兼容C++03,而C++03 又力图兼容 C++98,C++98 则力图兼容C语言。这个向下兼容的特色是C++如此强大和有用的主要原因之一。因此,通过复习C++03 的书籍中的内容,充分利用C++语言的兼容性,在原先的书籍基础上添加新的章节来介绍C++11的东西,这种思路非常的诱人。采取这样的做法会让事情简单很多:因为原书中的大部分内容不需要改动。

当然,这样做的瑕疵就是,语言的新特性会变成一种“附加题”——也就是说,在理解了该语言的所有原有内容后,在“附加练习”时才会去考虑学习这些新的特性。这样一来,就很可能造成部分读者最后完全没有学到新的东西。举个例子吧,有这么一种现象就是,很多人去学习C++编程,但是他们最后学到的只是如何去用C++的编译器编译C语言程序。在C++11的情况下,也就很可能造成许多人实际上只学到了如何用新的编译器去编译C++03的程序,仅此而已。

这儿有一个简单的例子可以说明这种现象。假设v是一个vector<int>泛型,我们期望调用一个方法foo去遍历v中的每个元素。在C++03里面,我们就可以这么做:
行号 开/关 | 展开/收缩 | 全选
  1.  
  2. for (vector<int>::size_type i = 0; i != v.size(); ++i)
  3.     foo(v[i]);
  4.  

当然,更优雅的办法是使用迭代器iterator,这样做的好处是能够有效地避免使用下标:
行号 开/关 | 展开/收缩 | 全选
  1.  
  2. for (vector<int>::iterator it = v.begin(); it := v.end(); ++it)
  3.     foo(*it);
  4.  

如果我们利用C++11的语法代码去实现上述的功能,那写法会非常不同。比如,我们首先写一个例子,看上去像这样:
行号 开/关 | 展开/收缩 | 全选
  1.  
  2. for (decltype(v.size()) i = 0; i != v.size(); ++i)
  3.     foo(v[i]);
  4.  

然后,我们还可以写成这样:
行号 开/关 | 展开/收缩 | 全选
  1.  
  2. for (auto it = v.begin(); it != v.end(); ++it)
  3.     foo(it);
  4.  

甚至是这样:
行号 开/关 | 展开/收缩 | 全选
  1.  
  2. for (auto x: v)
  3.     foo(x);
  4.  


如果一本书教了你前两种写法,那么后面提到的三种写法就成了“附加题”,多数人宁可去坚持使用前两种写法,而完全不去考虑如何记住后面三种写法。那么从效果来说,这本书就变成了一本“介绍C++03的书,顺带提及了C++11”,读者也就成了“学习C++03编程的人”,而不是学习C++11。如果真是如此,那么去写一本关于C++11的书,就完全没有必要了。

Barbara决定采用最艰难的方式写作:不仅讨论C++语言中的新特性,而且将这些新特性融入到本书的各个章节当中。在接下来的几周时间里,我会跟大家一起讨论一下关于本书中的一些例子,以及她所采取的写作策略。

你可能感兴趣的:(《C++ Primer第五版》如何修订原书)