文档介绍:“C++是个难学易用的语言”,这句话相信很多人心有戚戚。C++的学习难度,一在于语言本身太多的“幕”,二在于“paradigm shift”((思考模式的移转)。
传统程序语言如C,pascal,basic,fortran…,除了模样看起来稍有不同,基本上都是函数call来call去,大同小异,很容易掌握。你想做的动作,在code中都看得一清二楚。你所看不到的,荦荦大者也不过就是编译程序为你的函式加上用以处理堆栈的一小段码(prologue和epilogue),这一小段码基本上做的是housekeeping工作,你没看到也没有关系(更好),并不影响你对程序逻辑的思考。
C++不一样,C++有太多和程序逻辑息息相关的动作是编译程序为我们加上去的。换句话说C++编译程序为我们“加码”。如果不识清这一节,学习C++有如雾里看花,雾非雾,花非花。
编译程序为我们的C++程序加了什么码呢?很多!对象诞生时ctor会被唤起,物件死亡时dtor会被唤起,这都是加码的结果。ctor中设定vtpr和vtbl,这也是加码的结果。new 单一对象时会产生memory block cookie,new对象数组时会产生一个内部结构记录着object size 和class ctor…,这也都是布幕后的工作。可以说,程序代码中看不到而却必须完成的所有与程序逻辑有关的动作,统统都是C++ 编译程序加码后的结果。
当“继承”发生,整个情况变得稍微复杂起来。“多重继承”又更复杂一些,“虚拟继承”再更复杂一些。
这些布幕后的主题,统可归类为所谓的C++ object model(对象模型)。如果不知道这些底层机制,你就只能够把“make destructors virtual in base classes”(, item14)或“never treat arrays polymorphically”(, item 3)这类规则硬背下来,却不明白它的道理。
用一样东西,却不明白它的道理,林语堂如是说:“不高明”。只知道how,不知道why,侯捷如是说:“不高明”。
C++的第二个学习难度在于“paradigm shift”(思考模式的移转)。别说自己设计classes 了,光使用别人的classes,就都是一种思考模式和行为模式的移转。Mfc(或owl或vcl) programmer必然甚能够领略并体会我的意思。
使用所谓的application framework(一种大型的、凝聚性强的、有着面向对象公共基础建设的class library),你的码和framework之间究竟是怎样的关系呢?framework提供的一大堆可改写的虚拟函式的意义与价值究竟在哪里呢?为什么framework所设计的种种美好性质以及各式各样的算法竟然可以施行于我们自己设计的class types身上呢?framework被设计时,并不知道我们的存在呀!
这正是面向对象中的多型(polymorphism)的威力。
稍早所说的C++对象模型,偏属程序设计的低层面;这里所说的思考模式移转,则是程序设计的高层面。能够把新思维模式的威力发挥得最淋漓尽致的,当推面向对象的polymorphism(多型)和generalization(泛型)。如果你没有使用这两项特性,等于入C++宝山而空