关于C++的扯淡

来源:互联网 发布:王珮瑜 冯蕴 知乎 编辑:程序博客网 时间:2024/04/30 13:24

  
  今天下午在看C++Primer的时候跟同学东扯西扯一些乱七八糟的东西就填在这里。这本书还真的是不错的。 
   
  C++ 的诞生大约是在1980-1983年。总之我的一直以来的基本观点是,C++当初的诞生一定不是为了现在面向对象方法论上教授的那些扯淡的东西……什么把一个类的数据封装起来,只提供Get()和Set()接口来提高它的安全性啦,什么画一个业务流程图再转化为类图啦,之类的。C++的诞生离计算机的企业级大规模应用和面向对象设计方法论的诞生还有一段时间,它的作者是在想完成一些别的什么东西,一些比较特别的,在软件工程里面从未提到过的目标,嗯…… 
   
  虽然读了四年计算机系,但是因为一直在用C#和Java这类比较傻的语言,导致我个人对C++的接触过少……考完算法课就完事了。最近一直在被老板抽着写 C++程序,才终于对C++的理解稍微深入一些。事实上,C离C++之间只隔了7年,而数据类型这个概念是在C里面才引进的。在1973年之前,程序看到的就是一个一个的内存字节。短短7年的时间内,从C的数据类型演化为C++的数据与操作的集合称为“类”可以作为数据类型,这中间演化的动机,如果说是企业的ERP系统的需要,那是不可想象的。 
   
  如果用我扯淡的目光看来,最初的把操作和数据打包形成“类”作为数据类型的需求,可能源自运算符重载的需要。最初的动机可能在String类型之间没法进行大小比较,也没法赋值。因为char *显然做不到这两点。这个时候,工程师们意识到CPU对于数值的那一套指令集不能满足更多的类型的需要。如果所有新的类型都要能像经典的int一样能干这个那个,就必须能够让类的实例的行为可以自定义地编程。这个设计一口气诞生了两个结果,第一是伟大的操作和数据打包成为面向对象的“类”概念,第2是运算符重载。 
   
  但是,C++设计者的野心并没有就此打住。(如果是这样的话他们可能就发明了Java……)如果说对于任何的数据类型都可以比大小的话,那么“比大小”这件事情和与“比大小”有关的事情就不具有特定类型的语义了。我们应该能写一段程序,既能给int比大小,也能给 char比大小,也能给String比大小——于是,模版诞生了。模版的最主要贡献是类型代数;通过模版,我们只要写出对于一些代数符号的算法,然后把具体的类型代进去就可以了。 
   
  不过如果C++只是个有模版的语言的话那么模版和公共的纯虚接口类其实也没大区别,而C++的设计也远没有在此停下。它的设计者意识到,总体上来说,算法这种东西并不是普适的。一个“算法”一定作用于一群对象,(如果只作用于单个对象,那么该算法应该是该对象的成员方法而不是独立之外的东西)而这一群对象并不是任意选定的。例如,“排序”算法只有对能比出谁大谁小的一堆对象才能进行。(更严格地说,是对一堆能够选出可比较的键值的对象)如果比较对象是“红色”和“蓝色”,那任你怎么先进的排序算法也算不出个所以然来。换句话说,在C++的观点里,算法是作用于具有特定特性的对象集合的一组操作 。注意,这里的特性指的是这个集合 的特性而并非每个对象自身的特性。例如,“排序”算法只有作用于那些良序的或者说可以比较大小的集合上才有作用。在之前,我们已经有了强大模版;模版实现了针对单个对象的数据类型的抽象。此刻,我们需要一个对于一组对象构成的集合的特性的抽象:此时C++引进了容器和迭代器。 
   
  容器是一组以模版形式出现的泛型按照一定的规则构成的集合,而迭代器提供了符合这个集合特性的访问方法。它们是对数据结构的第二次抽象,在这层抽象上,C++开始讲述算法。此时,算法就是可以应用于一系列容器的操作的总和。在这个时候,不但具体的数据类型已经随着模版的抽象而消失,就连这种数据类型构成的集合本身 都已经随着容器到迭代器的抽象而消失了。(C++算法只能访问迭代器,而不能访问容器自身)算法面对的是纯粹的,由迭代器表达出来的“关系”;例如排序算法,它为之工作的目标只是一个“能够比较大小的”迭代器,以及这个队列的头和尾而已。具体提供这个迭代器的容器是vector还是map,算法并不知情。 
   
  C++Primer甚至赤裸裸地指出,C++中所有的算法都应该采取以下4种形式中的1种: 
   
  alg(beg, end, other params) 
   
  alg(beg, end, dest, other params) 
   
  alg(beg, end, beg2, other params) 
   
  alg(beg, end, beg2, end2, other params) 
   
  这简直就跟当年讨论图灵可计算性的理论在暴力和狂热程度上没有任何区别。尽管作者出于礼貌地写出了other params,不过C++的理想和信念就是只要透过前面那些参数,基于泛型容器的C++可以让任何的算法都用那前面的几个参数实现。换句话说,C++的设计目标,毫无疑问,是透过对于数据结构自身和对于数据结构的集合的双重抽象最终可以让程序员写出像数学公式一样“纯粹”的算法,这些算法应该只基于迭代器实现,它们应该优美、庄重、典雅,并且就像F=ma一样万年不变。 现在看来,STL尽管还在每年修修补补,不过C++设计的这项初衷应该算是部分达到了吧。 
   
  最后提一下C++和OO以及软件工程的区别。说实话,它们除了在把操作和数据一起打包成对象,并且对象可以继承这点上有偶然的巧合外,其余部分联系不大。 C++承认了OO对于世界万物皆为对象,并且对象之间应该存在着层级抽象关系的世界观,但是这只是工具而并非方向;就像大碗岛的下午描述的是海滩——然而它的重点并非华丽的男女,而是指出点彩法的运用——一样。

原创粉丝点击