下面讲述有关C++复杂性的问题,实际上C++复杂性是一个距离应用相当遥远的非常基础的程序库,其主体部分只相当于Java中System和Util两个package,接下来进行详细说明。
或有人说C++之关键缺陷是没有统一完整的类库支撑,Bjarne Stroustrup即强调此因素。然而这其实只不过是一个结果,而不是原因。正是因为语言太复杂,才无法在有效期内开发出高质量的大一统的类库。
C++复杂,并非是其体积庞大之必然结果。复杂是对结构混乱无序程度的描述,规模大,结构不见得必然复杂。C++的复杂,也并不是如很多人所认为,是若干种编程范式(paradigms)的并存而至。事实上,现代实用编程语言至少有2-3种范式才能登大雅之堂。以范式数量论,Python和Ruby等新型动态语言的范式甚至多于C++,然而它们却以简单和开发效率高著称。
C++复杂的根源在于三大约束:与C的完全兼容、静态类型检查、最高性能。在三大约束下,C++未能完善对于面向对象思想的支持,未能建立强大的动态能力,从而使得C++在OO这个单项上存在本质缺陷。
事实上,C++的过程、OB模型相当成熟和稳定,而泛型模型,就单项来说,除了语法丑陋之外也没有大的问题。缺陷集中体现在OO模型的实现,并因此干扰了其他几个范式的完整程度。
然而,OO的缺陷绝非设计者的偏执,其原因在于三大约束。如果坚持三大约束,则即使再重新设计一次,结果也与今日相差不远。Stroustrup在多种场合表示,对C++的设计没有大的后悔之处,意思就是这个。侯捷先生早在2001年初即对我说,C++在OO上不及Java,当时体会不深。
认为没有大一统的单根类库会使设计更加灵活,后来又认为凭借GP可以抵消OO的不足甚至超越之,现在看来即使不是不可能,这条道路也必然是艰辛异常,成败难以预料。又因为上述所有因素的综合作用,C++基础类库的建设只能进行到很低的高度上就停下来,因为再往上走就面临重重困境和无穷无尽的争论。
C++复杂性实际上是一个距离应用相当遥远的非常基础的程序库,其主体部分只相当于Java中System和Util两个package。而C++宁可停在这样的低层次,也不愿意放弃三大约束中的任何一个。这种执着使得高层标准库设施的建立异常困难,使用也不容易。Boost库中相当部分组件的易用性不佳。
模板的复杂语法与三大约束也有直接的关系。另一个原因是Bjarne在发明模板时目标单纯。C#和Java加入泛型机制的时候。没有继承C++最好的经验,却不约而同地继承了C++模板机制中最坏的部分——语法,短期来看,丧失了一次改革的良机。长远来看,必成累赘。
C++中的多种范式并行,是一些最复杂问题的表面原因。以至于Doug Lea建议在一个项目里只坚持一个范式。但是这仍然只是表象。归根结底还是因为OO的缺陷,使得与其它范式合作时困难成倍放大。故自接受Doug Lea思想以来,我的C++(乃至其他现代语言,尤其是Python等多范式语言)的开发设计思路是:
1. 首先选定一种思维方式(即范式),尽可能只用这一种思维方式解决问题;
2. 如果在局部遇到其他思维方式更得力的问题,则经慎重考虑后,可以将另一种风格包装在局部,解决局部问题。但整个系统在某一层次之上看来,应当是统一一致的。一般对C++复杂性说明,应以OB为基本风格。除非有类似MFC那样庞大而成熟的OO库支持,不应贸然在整体上使用OO风格。
3. 多种风格混用,除非有已被充分讨论并验证的方案(即成熟模式),可提供单一风格不能提供的较大优势,否则应极力避免。当然鼓励在研究中探索,但实践是另一回事。
【编辑推荐】