天啊,这本书竟是如此轻薄短小。我真想大叫一声“哇欧”!C++ Primer 加上索引、扉页、谢词之后,厚达1237 页,而此书却只有薄薄276 页。套句拳击术语,这是一部“轻量级”作品。
每个人都会好奇这究竟是怎么回事。的确,这里头有一段故事。
过去数年来,我不断缠着迪斯尼电影动画公司(Disney Feature Animation)的每一个人,请求让我亲身参与一部电影的制作。我缠着导演,甚至Mickey 本 人(如果我可以说出来的话),要求一份管理工作。我会如此疯狂,部分原因是深陷于好莱坞大屏幕那令人神往的无尽魔力而难以自拔。除了计算机科学方面的学 位,我还拥有艺术硕士的头衔,而电影工作似乎可以为我带来个人专长的某种整合。我要求管理工作,为的是从制片过程中获取经验,以便提供实际有用的工具。身 为一个C++编译器编写者,我一直都是自己最主要的用户之一。而你知道,当你是自己软件的主力抱怨者时,你就很难再为自己辩护或觉得受到不公平的责难。
《幻想曲2000》(Fantasia 2000)片中有一段火鸟(Firebird)的特效镜头。其计算机特效指导对于我的加盟颇感兴趣。不过,为了掂掂我的斤两,他要求我先写个工具,读入为某段场景所摄的原始数据,再由此产生可嵌入Houdini 动画套件中的摄影机节点(camera node)。当然,我用C++把它顺利搞定了。他们爱死它了,我也因此得到了我梦寐以求的工作。
有一次,在制片过程中(在此特别感谢Jinko 和Chyuan),我被要求以Perl 重写那个工具。其他的TD 并非编程高手,仅仅知道Perl、Tcl 之类的程序语言。(TD 是电影界的术语,指的是技术导演。我是这部片子的软件TD,我们还有一位灯光TD〔你好,Mira〕,一位模型TD〔你好,Tim〕,以及电影特效动画师〔你好,Mike,Steve,Tonya〕。)而且,喔,天啊,我得赶着点,因为我们想要获得一些观念上的实证,而导演(你好,Paul 和Gaetan)及特效总监(你好,Dave)正等着结果,准备呈给公司大头目(你好,Peter)。这虽然不是什么紧急要务,可是,你知道的……,唉。
这令我感到些许为难。我自信可以用C++快速完成,但我不懂Perl。好吧,我想,我去找本书抱抱佛脚好了——前提是这本书不能太厚,起码此刻不能太厚。而且它最好不要告诉我太多东西,虽然我知道我应该知道每一样东西,不过暂且等等吧。毕竟这只是一场表演:导演们需要一些经过证实的概念,艺术家需要一些东西协助证实其概念,而制片(你好,heck),她需要的是一天48 小时。此刻我不需要全世界最棒的Perl 大全,我需要的是一本能妥善引导我前进,使我不致偏离正轨过远的小书。
我找到了Randal Schwartz 的Learning Perl,它让我立即上手并进展神速,而且颇具阅读趣味。不过,就像其他有趣的计算机书籍一样,它也略去了不少值得一读的内容——尽管在那个时间点,我并不需要了解所有内容,我只需要让我的Perl 程序乖乖动起来。
我终于在感伤的心境中明白,C++ Primer 第三版其实无法扮演人们在初学C++时的导师角色。它太庞大了。当然,我还是认为它是一本让我骄傲的巨著——特别是由于邀请到Josée Lajoie 共同完成。但是,对于想立刻学会C++程序语言的人来说,这本巨著实在过于庞大复杂。这正是本书的由来。
你或许会想,C++又不是Perl。完全正确!本书也非Learning Perl,它谈的是如何学习C++。真正的问题在于,谁能够在散尽千页篇幅之后,犹敢自称教导了所有的东西呢?
1. 精细度。在计算机绘图领域中,精细度指的是影像被描绘出来的鲜明程度。画面左上角那位骑在马背上的匈奴人,需要一张看得清楚眼睛的脸、头发、五点钟方向的影子、衣服……。匈奴人的背后——不,不是那块岩石,老天——唔,相较之下无关紧要。因此我们不会以相同的精细度来描绘这两个影像。同样道理,本书的精细度在相当程度上做了降低。依我看,C++ Primer 除了在运算符重载(operator overloading)方面的实例讨论稍嫌不足外,可说极其完备了(我敢这么说是因为Josée 也有一份功劳)。但尽管如此,C++ Primer 还花了46 页篇幅讨论操作符重载,并附上了范例,而本书却仅以两页带过。
2. 语言核心。当我还是C++ Report 的编辑时,我常说,杂志编辑有一半工作花在决定哪些题材应该 放入,哪些不要。这句话对本书一样成立。本书内容是围绕在编程过程中所发生的一系列问题组织的。我介绍编程语言本身的特性,借此来为不同的问题提供解决之 道。书中并未述及任何一个可由多继承或虚继承解决的问题,所以我也就完全没有讨论这两个主题。然而,为了实现iterator class,我必须引入嵌套类型(nested type)。Class 的类型转换操作符很容易被错用,解释起来也很复杂,所以我不打算在书中提到它。诸如此类。我对题材的选择以及对语言特性的呈现顺序,欢迎大家指教批评。这是我的选择,也是我的职责。
3. 范例的数量。C++ Primer 有数百页代码,巨细糜遗,其中甚至包括一套面向对象的(Object Oriented)文本检索系统,以及十个左右的完整class。虽然本书也有代码,但数量远不及C++ Primer。为了弥补这项缺憾,我将所有习题解答都置于附录A。诚如我的编辑Deborah Lafferty所言,“如果你想提高教学速度,唾手可得的解答对于学习的强化极有帮助。”
结构与组织
本书由七章和两份附录构成。第1 章借着撰写一个具有互动性质的小程序,描绘C++语言预先定义的部分。这一章涵盖了内置的数据类型、语言预定义的运算符(operator)、标准库中的vector 和string、条件语句和循环语句、输入和输出用的iostream 库。我之所以在本章介绍vector 和string这两个class,是因为我想鼓励读者多多利用它们取代语言内置的数组(array)和C-style 字符串。
第2 章解释函数的设计与使用,并逐一查看C++函数的多种不同风貌,包括inline 函数、重载(over loaded)函数、function template,以及函数指针(pointers to functions)。
第3 章涵盖了所谓的Standard Template Library(STL):一组容器类(包括vector、list、set、map,等等)、一组作用于容器上的泛型算法(包括sort()、copy()、merge(),等等)。附录B 按字典顺序列出了最广为运用的泛型算法,并逐一附上了使用实例。
身为一个C++程序员,你的主要任务便是提交class 以及面向对象的class 层次体系。第4 章将带领你亲身了解class 机制的设计与使用过程。在这个过程中,你会看到如何为自身的应用系统建立起专属的数据类型。第5 章介绍如何扩展class,使多个相关的class 形成族系,支持面向对象的class 层次体系。以我在梦工厂动画电影公司(Dreamworks Animation)担任顾问的经验为例,那时我们设计了一些class,用来进行四个频道影像合成之类的工作。我们使用了继承和动态绑定(dynamic binding)技术,定义影像合成所需的class 层次体系,而不只是设计八个独立的class。
第6 章的重头戏是class template,那是建立class 时的一种先行描述,让我们得以将class 用到的一个(或多个)数据类型或数据值,抽离并参数化。以vector 为例,可能需要将其元素的类型加以参数化,而buffer 的设计不仅得将元素类型参数化,还得将其缓冲区容量参数化。本章的行进路线围绕在二分树(binary tree)class template 的实现上。
最后一章,第7 章,介绍如何使用C++的异常处理机制(exception handling facility),并示范如何将它融入标准库所定义的异常体系中。附录A 是本书习题解答。附录B 提供了关于最广为运用的一些泛型算法的相关讨论与使用实例。
关于源代码
本书的所有程序,以及习题解答中的完整代码,都可从网上获得。你可以在Addison Wesley Longman 的网站(www.awl.com/cseng/titles/0-201-48518-4)或我的个人首页(www.objectwrite.com)中取得。所有程序均在Visual C++ 5.0 环境中以Intel C++编译器测试过,也在Visual C++ 6.0 环境中以Microsoft C++编译器测试过。你或许需要稍微修改一下代码才能在自己的系统上编译成功。如果你需要做一些修改并且做了,请将修改结果寄一份给我(slippman@objectwrite.com),我会将它们附上你的大名,附于习题解答代码中。请注意,本书并未显现所有代码。
致谢
在这里,我要特别感谢C++ Primer 第三版的共同作者Josée Lajoie。不仅因为她为本书初稿提供了许多深入见解,更因为她在背后不断地给我鼓舞。我也要特别感谢Dave Slayton 以他那犀利的绿色铅笔,彻底审阅了文本内容与程序范例。Steve Vinoski 则以同情但坚决的口吻,为本书初稿提供了许多宝贵意见。
特别感谢Addison-Wesley 编辑团队:全书编辑Deborah Lafferty 从头到尾支持这个项目;审稿编辑Besty Hardinger 对本书文字的可读性贡献最大;产品经理John Fuller 带领我们把一堆文稿化为一本完整的图书。
撰写本书的过程中,我同时还担任独立顾问工作,因此必须兼顾书稿和客户。感谢我的客户对我如此体谅和宽容。我要感谢Colin Lipworth、Edwin Leonard、Kenneth Meyer,因为你们的耐心与信赖,本书才得以完成。
更多读物
内举不避亲,我要推荐C++书籍中最好的两本,那便是Lippman 与Lajoie 合著的C++ Primer,以及Stroustrup 的著作The C++ Programming Language。这两本书目前均为第3 版。我会在本书各主题内提供其他更深入的参考书目。以下是本书的参考书目。(你可以在C++ Primer 和The C++ Programming Language 中找到更广泛的参考文献。)
[LIPPMAN98] Lippman, Stanley and Josée Lajoie, C++ Primer, 3rd Editoin, Addison Wesley Longman, Inc.,Reading, MA (1998) ISBN 0-201-82470-1.
[LIPPMAN96a] Lippman, Stanley, Inside the C++ Object Model, Addison Wesley Longman, Inc., Reading,MA (1996) ISBN 0-201-83454-5.
[LIPPMAN96b] Lippman, Stanley, Editor, C++ Gems, a SIGS Books imprint, Cambridge University Press,Cambridge, England (1996) ISBN 0-13570581-9.
[STROUSTRUP97] Stroustrup, Bjarne, The C++ Programming Language, 3rd Editoin, Addison Wesley Longman, Inc., Reading, MA (1997) ISBN 0-201-88954-4.
[SUTTER99] Sutter, Herb, Exceptional C++, Addison Wesley Longman, Inc., Reading, MA (2000) ISBN 0-201-61562-2.
本文节选自《Essential C++中文版》一书
[美] Stanley B.Lippman 著
侯捷 译
电子工业出版社出版