标题：深度探索C 对象模型（传世经典书丛）
图书信息
传世经典书丛
深度探索C++对象模型

内容简介
作者Lippman参与设计了全世界第一套C++编译程序cfront，这本书就是一位伟大的C++编译程序设计者向你阐述他如何处理各种explicit（明确出现于C++程序代码中）和implicit（隐藏于程序代码背后）的C++语意。
本书专注于C++面向对象程序设计的底层机制，包括结构式语意、临时性对象的生成、封装、继承，以及虚拟——虚拟函数和虚拟继承。这本书让你知道：一旦你能够了解底层实现模型，你的程序代码将获得多么大的效率。Lippman澄清了那些关于C++额外负荷与复杂度的各种错误信息和迷思，但也指出其中某些成本和利益交换确实存在。他阐述了各式各样的实现模型，指出它们的进化之道及其本质因素。书中涵盖了C++对象模型的语意暗示，并指出这个模型是如何影响你的程序的。
对于C++底层机制感兴趣的读者，这必然是一本让你大呼过瘾的绝妙好书。
译 序
本立道生         
对于传统的结构化（sequential）语言，我们向来没有太多的疑惑，虽然在函数调用的背后，也有着堆栈建制、参数排列、返回地址、堆栈清除等等幕后机制，但函数调用是那么的自然而明显，好像只是夹带着一个包裹，从程序的某一个地点跳到另一个地点去执行。
但是对于面向对象（Object Oriented）语言，我们的疑惑就多了。究其因，这种语言的编译器为我们（程序员）做了太多的服务：构造函数、析构函数、虚拟函数、继承、多态……有时候它为我们合成出一些额外的函数（或运算符），有时候它又扩张我们所写的函数内容，放进更多的操作。有时候它还会为我们的objects加油添醋，放进一些奇妙的东西，使你面对sizeof的结果大惊失色。
我心里头一直有个疑惑：计算机程序最基础的形式，总是脱离不了一行一行的循序执行模式，为什么OO（面向对象）语言却能够“自动完成”这么多事情呢？另一个疑惑是，威力强大的polymorphism（多态），其底层机制究竟如何？
如果不了解编译器对我们所写的C++代码做了什么手脚，这些困惑永远解不开。
这本书解决了过去令我百思不解的诸多疑惑。我要向所有已具备C++多年程序设计经验的同好们大力推荐这本书。
这本书同时也是跃向组件软件（component-ware）基本精神的“跳板”。不管你想学习COM（Component Object Model）、CORBA（Common Object Request Broker Architecture）或是SOM（System Object Model），了解C++ Object Model，将使你更清楚软件组件（components）设计上的难点与运用之道。不但我自己在学习COM的道路上有此强烈的感受，Essential COM（《COM本质论》，侯捷译，碁峰1998）的作者Don Box也在他的书中推崇Lippman的这一本卓越的书籍。
是的，这当然不会是一本轻松的书籍。某些章节（例如3、4两章）可能给你立即的享受——享受于面对底层机制有所体会与掌控的快乐；某些章节（例如5、6、7三章）可能带给你短暂的痛苦——痛苦于艰难深涩、难以吞咽的内容。这些快乐与痛苦，其实就是我翻译此书时的心情写照。无论如何，我希望通过我的译笔，把这本难得的好书带到更多人面前，引领大家见识C++底层建设的技术之美。
侯捷  2011.10.20  于新竹
请注意：本书特点，作者Lippman在其前言中有很详细的描述，我不再多言。翻译用词与心得，记录在第0章（译者的话）之中，对您或有导读之功。
请注意：原文本有大大小小约80～90个笔误。有的无伤大雅，有的影响阅读顺畅甚巨（如前后文所用符号不一致、内文与图形所用符号不一致——甚至因而导致图片的文字解释不正确）。我已在第0章（译者的话）列出所有我找到的错误。此外，某些场合我还会在错误出现之处再加注，表示原文内容为何。这么做不是画蛇添足，也不为彰显什么。我知道有些读者拿着原文书和中译书对照着看，我把原书错误加注出来，可免读者怀疑是否我打错字或是译错了。另一方面也是为了文责自负……唔……万一Lippman是对的而J.J.Hou错了呢？！我虽有相当把握，但还是希望明白摊开来让读者检验。
目 录
本立道生（侯捷 译序） III
目录 VII
前言（Stanley B. Lippman） XIII
第0章  导读（译者的话） XXV
第1章  关于对象（Object Lessons） 1
第2章  构造函数语意学（The Semantics of Constructors） 37
第3章  Data语意学（The Semantics of Data） 83
第4章  Function语意学（The Semantics of Function） 139
第5章  构造、析构、拷贝语意学（Semantics of Construction, 
第6章  执行期语意学（Runtime Semantics） 237
第7章  站在对象模型的尖端（On the Cusp of the Object Model） 279
前 言
差不多有10年之久，我在贝尔实验室（Bell Laboratories）埋首于C++的实现任务。最初的工作是在cfront上面（Bjarne Stroustrup的第一个C++编译器），从1986年的1.1版到1991年9月的3.0版。然后移转到Simplifier（这是我们内部的命名），也就是Foundation项目中的C++对象模型部分。在Simplifier设计期间，我开始酝酿本书。
Foundation项目是什么？在 Bjarne 的领导下，贝尔实验室中的一个小组探索着以C++完成大规模程序设计时的种种问题的解决之道。Foundation项目是我们为了构建大系统而努力定义的一个新的开发模型（我们只使用C++，并不提供多重语言的解决方案）。这是个令人兴奋的工作，一方面是因为工作本身，一方面是因为工作伙伴：Bjarne、Andy Koenig、Rob Murray、Martin Carroll、Judy Ward、Steve Buroff、Peter Juhl，以及我自己。Barbara Moo管理我们这一群人（Bjarne和Andy除外）。Barbara Moo常说管理一个软件团队，就像放牧一群骄傲的猫。
我们把Foundation想象成一个核心，在那上面，其他人可以为使用者铺设一层真正的开发环境，把它整修为他们所期望的UNIX或Smalltalk模型。私底下我们把它称为Grail（传说中耶稣最后晚餐所用的圣杯），人人都想要，但是从来没人找到过！
Grail使用一个由Rob Murray发展出来并命名为ALF的面向对象层次结构，提供一个永久的、以语意为基础的表现法。在Grail中，传统编译器被分解为数个各自分离的可执行文件。parser负责建立程序的ALF表现法。其他每一个组件（如type checking、simplification、code generation）以及工具（如browser）都在程序的一个ALF表现体上操作（并可能加以扩展）。Simplifier是编译器的一部分，处于type checking和code generation之间。Simplifier 这个名称是由Bjarne所倡议的，它原本是cfront的一个阶段（phase）。
在type checking和code generation之间，Simplifier做什么事呢？它用来转换内部的程序表现。有三种转换风味是任何对象模型都需要的：
1．与编译器息息相关的转换（Implementation-dependent transformations）
这是与特定编译器有关的转换。在ALF之下，这意味着我们所谓的“tentative”nodes。例如，当parser看到这个表达式：
fct();
它并不知道是否（a）这是一个函数调用操作，或者（b）这是overloaded call operator在class object fct上的一种应用。默认情况下，这个式子所代表的是一个函数调用，但是当（b）的情况出现，Simplifier 就要重写并调换 call subtree。
2．语言语意转换（Language semantics transformations）
这包括constructor/destructor的合成和扩展、memberwise初始化、对于memberwise copy的支持、在程序代码中安插conversion operators、临时性对象，以及对constructor/destructor的调用。
3．程序代码和对象模型的转换（Code and object model transformations）
这包括对virtual functions、virtual base class和inheritance的一般支持、new和delete运算符、class objects所组成的数组、local static class instances、带有非常量表达式（nonconstant expression）之global object的静态初始化操作。我对Simplifier所规划的一个目标是：提供一个对象模型体系，在其中，对象的实现是一个虚拟接口，支持各种对象模型。
最后两种类型的转换构成了本书的基础。这意味着本书是为编译器设计者而写的吗？不是，绝对不是！这本书是由一位编译器设计者针对中高级C++程序员所写的。隐藏在这本书背后的假设是，程序员如果了解C++对象模型，就可以写出比较没有错误倾向而且比较有效率的代码。
什么是C++对象模型
有两个概念可以解释C++对象模型：
1. 语言中直接支持面向对象程序设计的部分。
2. 对于各种支持的底层实现机制。
语言层面的支持，涵盖于我的C++ Primer一书以及其他许多C++书籍当中。至于第二个概念，则几乎不能够于目前任何读物中发现，只有[ELLIS90]和[STROUP94]勉强有一些蛛丝马迹。本书主要专注于C++对象模型的第二个概念。本书语言遵循C++委员会于1995冬季会议中通过的Standard C++草案（除了某些细节，这份草案应该能够反映出此语言的最终版本）。
C++对象模型的第一个概念是一种“不变量”。例如，C++ class的完整virtual functions在编译时期就固定下来了，程序员没有办法在执行期动态增加或取代其中的某一个。这使得虚拟调用操作得以快速地派送（dispatch）结果，付出的成本则是执行期的弹性。
对象模型的底层实现机制，在语言层面上是看不出来的——虽然对象模型的语意本身可以使得某些实现品（编译器）比其他实现品更接近自然。例如，virtual function calls，一般而言是通过一个表格（内含virtual functions地址）的索引而决议得知。一定要使用如此的 virtual table 吗？不，编译器可以自由引进其他任何变通做法。如果使用virtual table，那么其布局、存取方法、产生时机以及数百个细节也都必须决定下来，而所有决定也都由每一个实现品（编译器）自行取舍。不过，既然说到这里，我也必须明白告诉你，目前所有编译器对于virtual function的实现法都是使用各个class专属的virtual table，大小固定，并且在程序执行前就构造好了。
如果C++对象模型的底层机制并未标准化，那么你可能会问：何必探讨它呢？主要的理由是，我的经验告诉我，如果一个程序员了解底层实现模型，他就能够写出效率较高的代码，自信心也比较高。一个人不应该用猜的方式，或是等待某大师的宣判，才确定“何时提供一个copy constructor而何时不需要”。这类问题的解答应该来自于我们自身对对象模型的了解。
写本书的第二个理由是为了消除我们对于C++语言（及其对面向对象的支持）的各种错误认识。下面一段话节录自我收到的一封信，来信者希望将C++引进于其程序环境中：
我和一群人工作，他们过去不曾写过（或完全不熟悉）C++和OO。其中一位工程师从1985就开始写C了，他非常强烈地认为C++只对那些user-type程序才好用，对server程序却不理想。他说如果要写一个快速而有效率的数据库引擎，应该使用C而非C++。他认为C++庞大又迟缓。
C++当然并不是天生地庞大又迟缓，但我发现这似乎成为C程序员的一个共识。然而，光是这么说并不足以使人信服，何况我又被认为是C++的“代言人”。本书就是企图极尽可能地将各式各样的Object facilities（如inheritance、virtual functions、指向class members的指针……）所带来的额外负荷说个清楚。
除了我个人回答这封信外，我也把此信转寄给HP的Steve Vinoski；先前我曾与他讨论过C++的效率问题。以下节录自他的回应：
过去数年我听过太多与你的同事类似的看法。许多情况下，这些看法是源于对C++事实真相的缺乏了解。在上周，我和一位朋友闲聊，他在一家IC制造厂服务，他说他们不使用C++，因为“它在你的背后做事情”。我连连追问，于是他说根据他的了解，C++调用malloc()和free()而不让程序员知道。这当然不是真的。这是一种所谓的迷思与传说，引导出类似于你的同事的看法……
在抽象性和实际性之间找出平衡点，需要知识、经验以及许多思考。C++的使用需要付出许多心力，但是我的经验告诉我，这项投资的回报率相当高。
我喜欢把本书想象成是我对那一封读者来信的回答。是的，本书是一个知识陈列库，帮助大家去除围绕在C++四周的迷思与传说。
如果C++对象模型的底层机制会因为实现品（编译器）和时间的变动而不同，我如何能够对于任何特定主题提供一般化的讨论呢？静态初始化（Static initialization）可为此提供一个有趣的例子。
已知一个class X有着constructor，如下面所示：
class X
{
friend istream&
operator>>( istream&, X& );
public:
X( int sz = 1024 ) { ptr = new char[ sz ]; }
...
private:
char *ptr;
};
而一个class X的global object的声明，如下面所示：
X buf;
int main()
{
// buf 必须在这个时候构造起来
cin >> setw( 1024 ) >> buf;
...
}
C++对象模型保证，X constructor将在main()之前便把buf初始化。然而它并没有说明这是如何办到的。答案是所谓的静态初始化（static initialization），实际做法则有赖开发环境对此的支持属于哪一层级。
原始的cfront实现品不单只是假想没有环境支持，它也假想没有明确的目标平台。唯一能够假想的平台就是UNIX及其衍化的一些变体。我们的解决之道也因此只专注在UNIX身上：我们使用nm命令。CC命令（一个UNIX shell script）产生出一个可执行文件，然后我们把nm施行于其上，产生出一个新的.c文件。然后编译这个新的.c文件，再重新链接出一个可执行文件（这就是所谓的munch solution）。这种做法是以编译器时间来交换移植性。
接下来是提供一个“平台特定”解决之道：直接验证并穿越COFF-based程序的可执行文件（此即所谓的 patch solution），不再需要nm、compile、relink。COFF 是Common Object File Format的缩写，是System V pre-Release 4 UNIX系统所发展出来的格式。这两种解决方案都属于程序层面，也就是说，针对每一个需要静态初始化的.c文件，cfront 会产生出一个sti函数，执行必要的初始化操作。不论是patch solution还是munch solution，都会去寻找以sti开头的函数，并且安排它们以一种未被定义的顺序执行（由安插在main()之后第一行的一个library function _main()执行之）（译注：本书第6章对此有详细说明）。
System V COFF-specific C++编译器与cfront的各个版本平行发展。由于瞄准了一个特定平台和特定操作系统，此编译器因而能够影响链接器特地为它修改：产生出一个新的.ini section，用以收集需要静态初始化的objects。链接器的这种扩充方式，提供了所谓的environment-based solution，那当然更在program-based solution层次之上。
至此，任何以cfront program-based solution为基础的一般化（泛型）操作将令人迷惑。为什么？因为C++已经成为主流语言，它已经接收了越来越多的environment-based solutions。本书如何维护其间的平衡呢？我的策略如下：如果在不同的C++编译器上有重大的实现技术差异，我就至少讨论两种做法。但如果 cfront之后的编译器实现模型只是解决cfront原本就已理解的问题，例如对虚拟继承的支持，那么我就阐述历史的演化。当我说到“传统模型”时，我的意思是Stroustrup的原始构想（反映在cfront身上），它提供一种实现模范，在今天所有的商业化实现品上仍然可见。
本书组织
第1章，关于对象（Object Lessons），提供以对象为基础的观念背景，以及由C++提供的面向对象程序设计范式（paradigm。译注：关于paradigm这个字，请参阅本书第1章第22页的译注）。本章包括对对象模型的一个概述，说明目前普及的工业产品，但没有对于多重继承和虚拟继承有太靠近的观察（那是第3章和第4章的重头戏）。
第2章，构造函数语意学（The Semantics of Constructors），详细讨论constructor 如何工作。本章谈到constructors何时被编译器合成，以及给你的程序效率带来什么样的意义。
第3章至第5章是本书的重要内容。在这里，我详细地讨论了C++对象模型的细节。第3章，Data语意学（The Semantics of Data），讨论data members的处理。第4章，Function语意学（The Semantics of Function），专注于各式各样的member functions，并特别详细地讨论如何支持virtual functions。第5章，构造、析构、拷贝语意学（Semantics of Construction, Destruction, and Copy），讨论如何支持class模型，也讨论到object的生命期。每一章都有测试程序以及测试数据。我们对效率的预测，将拿来和实际结果做比较。
第6章，执行期语意学（Runtime Semantics），查看执行期的某些对象模型行为。包括临时性对象的生命及其死亡，以及对new运算符和delete运算符的支持。
第7章，在对象模型的尖端（On the Cusp of the Object Model），专注于exception handling、template support、runtime type identification。
预定的读者
本书可以扮演家庭教师的角色，不过它定位在中级以上的C++程序员，而非C++新手。我尝试提供足够的内容，使它能够被任何有点C++基础（例如读过我的C++ Primer并有一些实际编程经验）的人接受。理想的读者是，曾经有过数年的C++编程经验，希望进一步了解“底层做些什么事”的人。书中某些部分甚至对于C++高手也具有吸引力，如临时性对象的产生，以及named return value（NRV）最佳化的细节等等。在与本书素材相同的各个公开演讲场合中，我已经证实了这些材料的吸引力。
程序范例及其执行
本书的程序范例主要有两个目的：
1. 为了提供书中所述C++对象模型各种概念的具体说明。
2. 提供测试，以测量各种语言性质的相对成本。
无论哪一种意图，都只是为了展现对象模型。举例而言，虽然我在书中有大量的举例，但我并非建议一个真实的3D graphic library必须以虚拟继承的方式来表现一个3D点（不过，你可以在[POKOR94]中发现作者Pokorny的确是这么做的）。
书中所有测试程序都在一部SGI Indigo2xL上编译执行，使用SGI 5.2 UNIX操作系统中的CC和NCC编译器。CC是cfront 3.0.1版（它会产生出C代码，再由一个C编译器重新编译为可执行文件）。NCC是Edison Design Group的C++ front-end 2.19版，内含一个由SGI供应的程序代码产生器。至于时间测量，是采用UNIX的timex命令针对1 000万次迭代测试所得的平均值。
虽然在xL机器上使用这两个编译器，对读者而言可能觉得有些神秘，我却觉得对此书的目的而言，很好。不论是cfront或现在的Edison Design Group's C++ front-end（Bjarne称其为“cfront的儿子”），都与平台无关。它们是一种一般化的编译器，被授权给34家以上的计算机制造商（其中包括Gray、SGI、Intel）和软件开发环境厂商（包括Centerline和Novell，后者是原先的UNIX软件实验室）。效率的测量并非为了对目前市面上的各家编译系统做评比，而只是为了提供C++对象模型之各种特性的一个相对成本测量。至于商业评比的效率数据，你可以在几乎任何一本计算机杂志的计算机产品检验报告中获得。
致谢
略
参考书目 
略
第0章 导读（译者的话）
读者对象很不容易三言两语就说明此书的适当读者。作者Lippman参与设计了全世界第一套C++编译器cfront，本书就是一位伟大的C++编译器设计者向你阐述他如何处理各种explicit（明确出现于C++程序代码）和implicit（隐藏于程序代码背后）的C++语意。
对于C++程序老手，这必然是一本让你大呼过瘾的绝妙好书。
C++老手分两类：一种人把语言用得烂熟，OO观念也有；另一种人不但如此，还对于台面下的机制，如编译器合成的default constructor、object的内存布局等有莫大的兴趣。本书对于第二类老手的吸引力自不待言；至于第一类老手，或许你没那么大的刨根究底的兴趣，不过我还是非常推荐你阅读此书。了解C++对象模型，绝对有助于你在语言本身以及面向对象观念两方面的层次提升。
你需要细细推敲每一个句子、每一个例子，囫囵吞枣是完全没有用的。作者是C++大师级人物，并且参与开发了第一套C++编译器，他的解说以及诠释鞭辟入里，你务必在看过每一小段之后，融会贯通，把思想观念化为己有，再接续另一小节。但阅读顺序并不需要按照书中的章节排列。
阅读顺序我个人认为，第1、3、4章最能带给读者迅速而最大的帮助，这些都是经常引起程序员困惑的主题。作者在这些章节中有不少示意图（我自己也加了不少）。你或许可以从这三章挑着看起。
其他章节比较晦涩一些（我的感觉），不妨“视可而择之”。
当然，这都是十分主观的认定。客观的意见只有一个：你可以随你的兴趣与需求，从任一章开始看起。各章之间没有必然关联性。
翻译风格太多朋友告诉我，他们阅读中文计算机书籍，不论是著作或译作，最大的阅读困难在于一大堆没有标准译名的技术名词或习惯用语（至于那些误谬不知所云的奇怪作品当然本就不在考虑之列）。其实，就算国家相关机构指定了统一译名（或曾有过，谁知道？），流通于工业界与学术界之间的还是原文名词与术语。
对于工程师，我希望我所写的书和我所译的书能够让各位读来通体顺畅；对于学生，我还希望多发挥一点引导的力量，引导各位多使用、多认识原文术语和专有名词，不要说出像“无模式对话盒（modeless dialog）”这种奇怪的话。
由于本书读者定位之故，我决定保留大量的原文技术名词与术语。我清楚地知道，在我们的技术领域里，研究人员或工程师如何使用这些语汇。
当然，有些中文译名应用较普遍，也较贴切，我并不排除使用。其间的挑选与决定，不可避免地带了点个人色彩。
下面是本书出现的原文名词（按字母排序）及其意义：
英文名词 中文名词或（及）其意义
access level 访问级，存取级。就是C++的public、private、protected三种等级
access section 访问区段，存取区段。就是class中的public、private、protected三种段落
alignment 边界调整，调整至某些bytes的倍数。其结果视不同的机器而定。例如32位机器通常调整至4的倍数
bind 绑定，将程序中的某个符号真正附着（决议）至一块实例上
chain 串链
class 类
class hierarchy class体系，class层次结构
composition 组合。通常与继承（inheritance）一同讨论
concrete inheritance 具体继承（相对于抽象继承）
constructor 构造函数
data member 数据成员（或被称为member variable）
declaration，declare 声明
definition，define 定义（通常附带“在内存中挖一块空间”的行为）
derived 派生
destructor 析构函数
encapsulation 封装
explicit 显式的（通常指C++程序代码中明确出现的）
hierarchy 体系，层次结构
implement 实现（动词）
implementation 实现品、实现物。本书有时候指C++编译器。大部分时候是指class member function的内容
implicit 隐式的、暗喻的（通常指未出现在C++程序代码中的）
inheritance 继承
inline 内联（C++的一个关键词）
instance 实例（有些书籍译为“案例”，极不妥当）
layout 布局。本书常常出现这个字，意指object在内存中的数据分布情况
mangle 名称切割重组（C++对于函数名称的一种处理方式）
member function 成员函数。或被称为function member
members 成员，泛指data members和member functions
object 对象（根据class的声明而完成的一份占有内存的实例）
offset 偏移位置
operand 操作数
operator 运算符
overhead 额外负担（因某种设计，而导致的额外成本）
overload 重载
overloaded function 多载函数
override 改写（对virtual function的重新设计）
paradigm 范式（请参考第1章第22页）
pointer 指针
polymorphism 多态（“面向对象”最重要的一个性质）
programming 程序设计、程序化
reference 参考、引用（动词）
reference C++的&运算符所代表的东西。当做名词解
resolve 决议。函数调用时链接器所进行的一种操作，将符号与函数实例产生关联。如果你调用func()而链接时找不到func()实例，就会出现“unresolved externals”链接错误
slot 表格中的一格（一个元素），条孔，条目，条格
subtype 子类型
type 类型，类别（指的是int、float等内建类型，或C++ classes等自定类型）
virtual 虚拟
virtual function 虚拟函数
virtual inheritance 虚拟继承
virtual table 虚拟表格（为实现虚拟机制而设计的一种表格，内放virtual functions的地址）
有时候考虑到上下文的因素，面对同一个名词，在译与不译之间，我可能会有不同的选择。例如，面对“pointer”，我会译为“指针”，但由于我并未将reference译为“参考”（实在不对味），所以如果原文是“the manipulation of a pointer or reference in C++……”，为了中英对等或平衡的缘故，我不会把它译为“C++中对于指针和reference的操作行为……”，我会译为“C++中对于pointer和reference的操作行为……”。
译注
书中有一些译注。大部分译注，如果比较短的话，会被我直接放在括号之中，接续本文。较长的译注，则被我安排在被注文字的段落下面（紧临，并加标示）。
原书错误这本书虽说质地极佳，但制作的严谨度却不及格！有损Lippman的大师地位。
属于“作者笔误”之类的错误，比较无伤大雅，例如少了一个；符号，或是多了一个；符号，或是少了一个}符号，或是多了一个）符号，等等。比较严重的错误，是程序代码变量名称或函数名称或class名称与文字叙述不一致，甚或是图片中对于object布局的画法，与程序代码中的声明不一致。这两种错误都会严重耗费读者的心神。
只要是被我发现的错误，都已被我修正。以下是错误更正列表。
 示例：L5表示第5行，L-9表示倒数第9行。页码所示为原书页码。
页码 原文位置 原文内容 应修改为
p.35 最后一行 Bashful(), Bashful();
p.57 表格第二行 1.32.36 1:32.36
p.61 L1 memcpy...程序代码最后少了一个） 
p.61 L10 Shape()...程序代码最后少了一个} 
p.64 L-9 程序代码最后多了一个 ; 
p.78 最后四行码 == 似乎应为 =
p.84 图3.1b说明 struct Point3d class Point3d
p.87 L-2 virtual...程序代码最后少了一个； 
p.87 全页多处 pc2_2（不符合命名意义） pc1_2（符合命名意义）
p.90 图3.2a说明 Vptr placement and end of class Vptr placement at end of class
p.91 图3.2b __vptr__has_vrts __vptr__has_virts
p.92 码L-7 class Vertex2d class Vertex3d
p.92 码L-6 public Point2d public Point3d
p.93 图3.4说明 Vertex2d的对象布局 Vertex3d的对象布局
p.92~p.94  符号名称混乱，前后误谬不符 已全部更改过
p.97 码L2 public Point3d, public Vertex 配合图3.5a和图3.5b，应调整顺序为public Vertex, public Point3d
p.99 图3.5a 符号与书中程序代码多处不符 已全部更改过
p.100 图3.5b 符号与书中程序代码多处不符 已全部更改过
p.100 L-2 ? pv3d + ...最后多了一个) 
p.106 L16 pt1d::y pt2d::_y
p.107 L10 & 3d_point::z; &Point3d::z;
p.108 L6 & 3d_point::z; &Point3d::z;
p.108 L-6 int d::*dmp, d *pd int Derived::*dmp, Derived *pd
p.109 L1 d *pd Derived *pd
p.109 L4 int b2::*bmp = &b2::val2; int Base2::*bmp = &Base2::val2;
p.110 L2 不符合稍早出现的程序代码 把pt3d改为Point3d
p.115 L1 magnitude() magnitude3d()
p.126 L12 Point2d pt2d = new Point2d; ptr = new Point2d;
p.136 图4.2右下 Derived::~close() Derived::close()
p.138 L-12 class Point3d...最后少了一个{ 
p.140 程序代码 没有与文字中的class命名一致 所有的pt3d改为Point3d
p.142 L-7 if ( this ...程序代码最右边少了一个) 
p.143 程序代码 没有与文字中的class命名一致 所有的pt3d改为Point3d
p.145 L-6 pointer::z() Point::z()
p.147 L1 pointer::*pmf Point::*pmf
p.147 L5 point::x() Point::x()
p.147 L6 point::z() Point::z()
p.147 中段码L-1 程序代码最后缺少一个） 
p.148 中段码L1 （ptr->*pmf）函数最后少了一个； 
p.148 中段码L-1 （*ptr->vptr[..函数最后少了一个） 
p.150 程序代码 没有与文字中的class命名一致 所有的pt3d改为Point3d
p.150 L-7 pA.__vptr__pt3d...最后少了一个； 
p.152 L4 point new_pt; Point new_pt;
p.156 L7 { }
p.160 L11, L12 Abstract_Base Abstract_base
p.162 L-3 Abstract_base函数最后少了一个； 
p.166 中，码L3 Point1 local1 = ... Point local1 = ...
p.166 中，码 L4 Point2 local2; Point local2;
p.174 中，码L-1 Line::Line()函数最后多了一个； 
p.174 中下，码L-1 Line::Line()函数最后多了一个； 
p.175 中上，码L-1 Line::~Line()函数最后多了一个； 
p.182 中下，码L6 Point3d::Point3d() PVertex::PVertex()
p.183 上，码L9 Point3d::Point3d() PVertex::PVertex()
p.185 上，码L3 y = 0.0之前缺少float 
p.186 中下，码L6 缺少一个return 
p.187 中，码L3 const Point3d &p const Point3d &p3d
p.204 下，码L3 缺少一个return 1; 
p.208 中下，码L2 new Pvertex; new PVertex;
p.219 上，码L1 __nw(5*sizeof(int)); __new(5*sizeof(int));
p.222 上，码L8 // new ( ptr_array...程序代码少了一个； 
p.224 中，码L1 Point2w ptw = ... Point2w *ptw = ...
p.224 下，码L5 operator new()函数定义多了一个； 
p.225 上，码L2 Point2w ptw = ... Point2w *ptw = ...
p.226 下，码L1 Point2w p2w = ... Point2w *p2w = ...
p.229 中，码L1 c.operator==( a + b ); c.operator=( a + b );
p.232 中下，码L2 x xx; X xx;
p.232 中下，码L3 x yy; X yy;
p.232 下，码L2 struct x _1xx; struct X _1xx;
p.232 下，码L3 struct x _1yy; struct X _1yy;
p.233 码L2 struct x __0__Q1; struct X __0__Q1;
p.233 码L3 struct x __0__Q2; struct X __0__Q2;
p.233 中，码 if条件句的最后多了一个； 
p.253 码L-1 foo()函数最后多了一个；
推 荐我个人翻译过不少书籍，每一本都精挑细选后才动手。（品质不够的原文书，译它做啥?!）在这些译本当中，我从来不做直接而露骨的推荐。好的书籍自然而然会得到识者的欣赏。过去我译的那些明显具有实用价值的书籍，总有相当数量的读者有强烈的需求，所以我从不担心没有足够的人来为好书散播口碑。但Lippman的这本书不一样，它可能不会为你带来明显而立即的实用性，它可能因此在书店中蒙上一层灰（其原文书我就没听说多少人读过），枉费我从众多原文书中挑出这本好书。我担心听到这样的话：
对象模型？呵，我会写C++程序，写得一级棒，这些属于编译器层面的东西，于我何有哉！
对象模型是深层结构的知识，关系到“与语言无关、与平台无关、跨网络可执行”软件组件（software component）的基础原理。也因此，了解C++对象模型，是学习目前软件组件三大规格（COM、CORBA、SOM）的技术基础。
如果你对软件组件（software component）没有兴趣，C++对象模型也能够使你对虚拟函数、虚拟继承、虚拟接口有脱胎换骨的新认知，或是对于各种C++写法所带来的效率利益有通盘的认识。
我因此要大声地说：有经验的C++ programmer都应该看看这本书。
如果你对COM有兴趣，我也要同时推荐你看另一本书：Essential COM，Don Box著，Addison Wesley公司1998年出版（《COM本质论》，侯捷译，碁峰1998）。这也是一本论述非常清楚的书籍，把COM的由来（为什么需要COM、如何使用COM）以循序渐进的方式阐述得非常深刻，是我所看过的最理想的一本COM基础书籍。
看Essential COM之前，你最好有这本Inside The C++ Object Model的基础。