未知 [信息技术] 开发工具比较之Visual C++ vs. Delphi     阅读:5335  

开发工具比较之Visual C++ vs. Delphi
作者: 不详 编辑: 海韵 发布日期: 2005-05-24 00:00:00 点击量: 5335 来源: haiyun.net
  引言

  “visual c++与delphi之比较”最近在csdn的论坛上的讨论非常火热,本文将以一个程序员的角度,从技术水平、功能、性能、易用性、稳定性、发展历程和前景等方面,以visual c++ 6和delphi 5为代表,尽可能客观地比较介绍visual c++和delphi这两大主流开发工具的优缺点,其中将涉及到语言、应用框架、控件、编译和连接、集成界面、调试、com、数据库开发等。本文还将对如何选择使用这两个开发工具提出一些建议。 

  值得一提的是,由于c++builder与delphi同为inprise公司产品,它们除了使用的语言不同,其余特性几乎都相同。因此本文对c++builder程序员和学习者也有参考价值。 

  语言:存在即是合理

  首先声明常被混淆的一点:vc和delphi本身不是语言,而是开发平台。它们所用的语言分别是略作扩展的c/c++和object pascal。我在网上常看到有人问应该学c/c++还是vc,这个问题很好回答:如果你学vc你就必须得学c/c++,或者说你学会了vc也就学会了c/c++了。

  言归正传,我们来比较一下c++和object pascal的优缺点。有人认为object pascal是“玩具语言”,c++才是“专业语言”,这是不对的。单从语言本身看,object pascal与c++属同一重量级。它们都是完全支持面向对象的语言,都扎根于“历史悠久”的面向过程的语言。c++是由c发展而来的,object pascal由pascal进化而来。它们都有很强的灵活性,都有自己的特长和不足。比如说,object pascal不支持多重继承、模板、操作符重载、内联函数定义、预处理、宏、全局静态类变量、嵌套类定义,等等,而这些都是c++支持的。但同样地c++也不支持object pascal的虚构造函数、过程嵌套、内置集合类型、内置字符串类型、"finally"构造等等,在rtti方面object pascal也比c++做得好。但这些并不重要,因为可以通过其它方式达到同样的目的,比如c++可以通过类扩展支持集合、字符串,object pascal可以通过“interface”多重继承,等等。关键是二者都可以很好地完成你手头的任务,这就够了。

  但是,仅仅比较语言本身是不够的,还得看它们的被接受和流行程度,学习曲线,发展前途,可移植性等,以及,很重要但常常被忽略的一点:与开发环境(指vc与delphi)及其应用框架的“磨合”程度。

  vc和delphi作为开发平台,很重要的一点就是提供了一个“无所不包”的应用框架:vc的mfc和delphi的vcl。mfc是用c++写的,vcl是用object pascal写的。当然,我们都知道,c++的使用范围比object pascal广得多,移植性也好得多。这本来是优点,但很有意思的是,正因为如此,微软写mfc时必须考虑最大限度减少对语言本身的改动,而把功夫下在源代码级,以便能尽可能支持ansi等标准,结果导致mfc的封装复杂而不直观。(尤其是它对消息的封装,下文还会提到。)太多的宏定义和含义模糊且自动生成、不得改动的注释使mfc乃至vc让很多新手望而生畏,不敢“下水”深入学习。而object pascal几乎是inprise“专用”的,不必考虑“标准”问题,因此inprise写vcl时就把全部精力放在了结构与性能上,结果语言与框架的磨合程度非常好。vcl框架的结构清晰,vcl代码的可读性非常好。许多人说delphi比较容易上手,也是这个缘故。天下没有白吃的午餐。你要工业标准吗?你要可移植性吗?(关于可移植性和兼容性,下文会详细比较。)那么请面对mfc的“天书”级代码吧。

  编译和连接:the need for speed 

  不同的语言带来的另一个不同是,编译和连接的速度的不同,以及执行速度的不同。delphi的编译和连接速度,毫不夸张地说,比vc快几十倍。即使把vc的incremental link选项打开,delphi的编译和连接速度仍比vc快好几倍。并不是说微软的编译器不行,这是由c++的复杂性决定的。模板的处理、预处理和宏的展开都是很费时的。前文不是提到object pascal没有模板、预处理和宏吗?这本来是缺点,但带来的一个好处就是编译速度极快。至于编译完的二进制代码,在打开相同的优化选项的情况下,delphi和vc执行速度并没有太大的差别。

  为了克服编译的速度问题,c++编译器一般需要增强的连接器和预处理机制。但是预处理机制仍然存在若干问题:

  1)程序调试的断点行可能和代码行不同。
  2)没有将最新的代码信息综合进去。
  3)容易产生错误的逻辑。
  4)因为读错文件头而很容易产生类似“unexpected end of file”的错误。

  两个编译器有个共同点是都能识别无用的“死”代码,比如一个没有用的函数等等。编译后的程序将不包含这些多余的信息。delphi在这方面作得更加出色。它可以让你在编辑器中可视化地提示出那行代码是“活”的、那行代码是“死”的。这样你就能整理出最精简的代码。

  delphi在编译后将在左边显示一个小蓝点表示这行代码是“活”的。visual c++做不到这点。 delphi编译后的可执行文件至少有200k(如果不使用vcl,仅仅使用winapi,文件的大小将大大缩小)。但是visual c++编程使用mfc编译后的可执行文件通常只有几十k,主要是因为微软已经将系统运行库包含在windows系统了(borland公司曾经和微软协商这个接口,但是微软利用操作系统的优势不愿意公开)。同样道理,使用bde开发的的数据库程序必须附带3-5m的额外系统文件,也是非常不协调的。

  非常有趣的是,delphi能够使用由c++ builder创建的的obj文件,但是使用上受很大的局限性。

  顺便提一下vc的“edit and continue”功能。在调试中,这个功能是可以大幅度节省时间的,但仍不能和delphi的闪速编译比。

  最后,visual c++的编译和连接时的错误信息比delphi要详细和具体的多。特别是使用atl开发更加如此。 

应用框架:mfc?有kfc流行吗?

  应用程序框架(application frame),有时也称为对象框架。visual c++采用的框架是mfc。mfc不仅仅是人们通常理解的一个类库。(同样,delphi的vcl也不仅仅是一个控件库,尽管它的名字叫“可视控件库”。)你如果选择了mfc,也就选择了一种程序结构,一种编程风格。mfc早在windows 3.x的时代就出现了,那时的visual c++还是16位的。经过这些年的不断补充和完善,mfc已经十分成熟。但由于原型出现得比较早,mfc相比于vcl落后了一个时代。尽管微软对mfc的更新没有停止,我也经常读到“只要windows不过时,mfc就不会过时”之类观点的文章,但就象inprise(原borland)的owl框架的淡出一样,mfc的淡出也是早晚的事。其实mfc是和owl同一个时代的产物。owl已经不在了,mfc怎能不“居安思危”呢?如果mfc青春永驻,微软的开发人员也不会“私自”开发出基于atl的wtl呀。当然,wtl的地位不能和mfc比,它并不是微软官方支持的框架,封装的功能也相当有限。但至少也反衬出了mfc存在的不足。

  我以为,最能体现一个应用程序框架的先进性的是它的委托模型,即对windows消息的封装机制。对windows api的封装就不用说了吧。大同小异,也没什么技术含量。如果高兴,你也可以自己写一个类库来封装。但对windows消息驱动机制的封装就不是那么容易的了。最自然的封装方式是采用虚成员函数。如果要响应某个消息就重载相应的虚函数。但出乎我的意料,mfc采用的是“古老”的宏定义方法。用宏定义方法的好处是省去了虚函数vtable的系统开销。(由于windows的消息种类很多,开销不算太小。)不过带来的缺点就是映射不太直观。对于mfc,则是“太不直观”了。它的消息映射代码虽然是可见的,但“劝君莫碰”。好在vc的classwizard可以自动生成消息映射代码,使用起来还算方便。但和vcl的委托模型相比,mfc的映射方法就显得太落后了。而delphi的object pascal因为没有“标准负担”,语言引入了组件、事件处理、属性等新特性。由于功夫做在编译器级,生成的源代码就显得十分简洁。似乎vc是“让框架迁就语言”,而delphi是“让语言迁就框架”。

  我想举一个对字符串操作的封装的例子来说明mfc和vcl的优缺点。在mfc中,cstringlist类有加入、获取、删除等功能,但vcl的tstringlist类除了上述功能还有排序、从逗号分隔的字串读入、流输入输出等功能。但同样的字符串替换功能,vcl的stringreplace要比mfc的cstring::replace慢2~3倍。总的来说,vcl的封装比mfc更为高层,更为抽象,但不可避免地带来的问题是某些部分执行效率比mfc略低。这就象低级语言(如汇编)的执行效率比高级语言(如basic)高,但编程效率较低。鱼和熊掌不可兼得嘛。

  vcl比之mfc的另一优点是对异常处理的支持,而一大缺点是对多线程支持差。vcl的大部分都不是针对多线程优化的。虽说vcl提供了简化多线程操作的类,但只是工作者线程(worker threads)使用起来比较简单。如果线程要和界面打交道的话事情就变得麻烦了,因为除了应用程序的主线程,任何线程不能访问任何可视的vcl部件。你不得不使用synchronize方法等待主线程处理它的消息,然后在主线程中访问vcl部件。而mfc就没有这样的限制。

  稳定性与完善程度:vc是老大哥

  vc要比delphi稳定和完善。vc的发展历史比delphi长,微软的总体实力比inprise强。vc的框架mfc经历了那么多年的发展和完善,功能非常全面,而且十分稳定,bug很少。其中你可能遇到的bug更少。而且有第三方的专门工具帮助你避开这些bug。如此规模的一个类库,能做到这一点不容易。不要小看了这一点,很多专业程序员就是为这个选择vc的。因为尽管vcl比mfc的抽象程度高,封装较为高层,但由此带来的开发效率的提高对高手来说毕竟是有限的。而如果你遇到一个怪问题,调试了半天,发现不是你的代码有错,而是vcl的bug,你作何感想?虽说遇到这类问题的可能性很小,但对vcl的形象的影响可不小。delphi的ide太占资源,启动速度太慢,和某些显卡驱动程序冲突,vcl中有bug,调试器不够健壮,对不稳定的第三方控件没有防护措施……问题多多,在这方面delphi不如vc。希望inprise能更上一层楼。顺便说一下,我在网上看到有些人极言delphi的不稳定,说几分钟出现20多次非法操作。delphi的确不如visual c++稳定,但也不至于如此呀。我估计是那位朋友的delphi装了某些有问题的第三方控件,导致了delphi的频频出错。不妨卸下那些控件试试? 

  可移植性:立足现实,放眼未来

  inprise正在开发delphi的linux版本,代号为kylix。也许通过kylix,用vcl构架编写的windows程序向linux移植成为可能。但这只是可能。因为在目前inprise的兼容性工作做得并不好。低版本的delphi不能使用高版本的vcl组件(这还别去说它),而高版本的delphi竟然不能使用低版本的vcl组件。真是岂有此理,我很少看见软件有不向下二进制兼容的。如果windows 98不能运行95的程序,windows 95不能运行3.x的程序,win 3.x不能运行dos程序,你还会用windows吗?如果windows 95的程序必须经过重新编译才能在98下运行,98会卖得那么好吗?“同门兄弟”c++builder和delphi也不能互相使用对方的组件,甚至同一套vcl库的文件名也不一样。所以一个组件有for d1/d2/d3/d4/d5/c1/c3/c4/c5这些不同版本是常有的事,而且随着delphi和c++builder版本的升级可能还会增加。希望inprise能先解决同门兄弟的兼容性问题。而微软的vc就没有这类问题。mfc1.0的程序也可以毫无障碍地在vc6.0下编译通过。

  集成界面:宏观与微观

  就大处说,vc的集成界面是不如delphi的。delphi仅仅一个object inspector就可以将vc的一堆wizards比下去,何况它还有code explorer、todo list等。但从小处,又可以看出delphi的不成熟。比如“自动完成”功能的智能化程度和提示详细程度不如vc,响应速度也没有vc快。

  visual c++所带的msdn是一部“开发者的百科全书”,信息庞大,查询方便,这方面比delphi更加专业。很多帮助项都有源程序示范。

  delphi的opentools是完全面向第三方的开放系统,开发者可以修改很多borland公司自身的功能,从ide的可扩充性上说delphi更好。

  调试:细微之处见真功 

  visual c++和delphi的调试功能都非常强大,同时都具有单步可视化调试、断点跟踪、运行时改变变量、鼠标指向可以得到变量值等等功能。对dll的输入输出也能方便的管理,能够进行源码级别的调试。

  相对而言,visual c++能够更加方便地看到变量的变化情况,这包括对结构可以展开成数据树,从而了解每一个变量的值,每一步调试,变化了的变量会加红,从而使调试更加方便。另外,visual c++的块内存察看比delphi也要方便。 

  当然,delphi也有很多体贴的细微之处,比如在线程调试的时候,delphi能够很方便地察看线程的变化,visual c++确必须要弹出一个模式对话框。 

  数据库开发:delphi一枝独秀

  数据库支持是delphi的强项。这主要体现在delphi与bde的无缝集成,以及delphi提供的那一大堆现成的数据库操作控件。这是vc望尘莫及的。目前delphi支持bde、ado、interbase三种数据库访问方式。所有的方式都能拖拉到应用程序中实现可视化操作。正是因为delphi对数据库类的包装,使得用户操作数据库不像在visual c++中必须从开始到最后都要干预。明显地提高了开发速度。

  在delphi中使用webbroker控件还能很方便地构造出基于数据库的web页面,通过html管理web数据库。

  visual c++访问数据主要通过ado和oledb,很多activex控件也能添加数据库功能。但是没有像paradox这样的桌面数据库,access相对太轻量级了。也许sql server是不错的选择。 

  com:新技术的力量

  com是组件对象模型的缩写。它是ole和activex技术的基础,com定义了一组api和一个二进制标准,让不同的编程语言、不同平台的彼此独立的对象相互进行通讯。

  com是microsoft制订的行业标准。但是,delphi也为com提供了强大的语言支持。支持接口、variant、宽字符串功能。这些对com的封装确实比c++更方便。比如在c++(没有类框架)进行com编程时,变体定义为oaidl.h文件中德variant结构。要处理变体,必须手工调整oleaut32.dll中variantxxxx() api函数对其进行初始化和管理,如variantinit()、variantcopy()、variantclear()等等。

  visual c++实现com编程有一种特殊的方法就是使用atl。atl使用visual c++特有的多重继承来实现com接口。虽然不见得实现com服务和控制更容易,但是atl和最新com技术的接口,基于模板的构造都比delphi强。atl更有利于建立小巧、快捷的com组件程序。 

  按照目前通用的观点,visual c++应用到com服务程序更有优势,delphi应用到com组件程序更合适。

  昨天,今天,明天 

  技术的进步在很多时候是此消彼长的。当初borland的turbo c和borland c++几乎是c/c++程序员唯一的选择。微软的quick c(现在还有人知道这个产品吗?)和microsoft c/c++从来也没有成为过主流。但borland c++又流行了多少年呢?不久就被新崛起的microsoft visual c/c++压下去了。于是inprise(原borland)拣起了当年turbo pascal和borland pascal的辉煌(事实上borland的成名作就是第一个pascal编译器),全力推出了delphi。delphi当初推出时被称为vb杀手,但vb现在仍然活得挺好。毕竟微软是靠basic起家的嘛,vb不是那么容易被打败的。inprise想了想不和vb争了,使用delphi的ide和vcl配上c++语言,推出了c++builder,又向visual c++的市场发起了夹攻。c++builder似乎是个不错的折衷选择了?再仔细想想!c++builder的优点delphi都有,但delphi的优点c++builder未必有。比如c++builder的编译速度比vc还慢,哪能和delphi比?而且因为vcl是object pascal写的,c++语言和vcl磨合得并不好。c++builder的bug比delphi还多,甚至sample代码中还有错。vcl的部分功能不能使用,要靠嵌入pascal代码访问。c++builder可用的第三方控件远没有delphi多。

  唉,真是金无足赤。microsoft和inprise,谁会笑在最后呢?

  鱼和熊掌:艰难的选择 

  选择一个开发工具依赖于很多不同的因素,每个人都能因为某种语言的某个缺陷而放弃学习或使用这种语言。任何程序员都希望自己喜欢的工具能达到理想的境界,通过上面不完善的比较,我想大家都有自己的看法。我们认为影响大家选择开发语言的因素主要包括: 

  1)哪门语言更容易入门? 

  学习一种语言需要投入大量的时间和精力。开发程序的开发成本是值得考虑的现实。一个熟练的delphi程序员和一个熟练的vc程序员工作效率是一样的。但是,成为熟练的程序员必须很快掌握一门语言的技巧。不幸的是,目前熟练的visual c++程序员是十里挑一。相对而言,delphi更适合初学者。 

  2)哪门语言有更多可继承的代码?

  语言代码的可重用性是加快开发效率明显方面,从早期的过程、函数到现在的组件技术都是朝这个目标在奋斗。这两种语言对代码重用的理解是不一样的,delphi主要通过vcl控件来实现代码重用,visual c++实现起来就比较复杂。 

  3)语言自身的本性。

  就技术(主要指应用框架)来说,delphi目前领先于visual c++。但稳定性和健壮性的不足又让我对inprise“想说爱你不容易”。而vc尽管发展到今日已十分完善,但mfc框架已是明日黄花了。如果不使用mfc,目前又没有合适的替代品。

  根据你的需要和实际情况做选择吧。实际上visual c++和delphi也不是单单竞争关系。它们在许多领域并不重叠,甚至是互补的。到底怎样取舍,要根据你的项目特性决定。如果你开发系统底层的东西,需要极好的兼容性和稳定性,选visual c++吧。你可以只调用windows的各种api,不用mfc。如果你写传统的windows桌面应用程序,visual c++的mfc框架是“正统”的选择;如果界面部分占这个应用程序代码比例较大的话,或者delphi中有相关功能的控件的话,delphi是事半功倍的选择。如果你为企业开发数据库、信息管理系统等高层应用(“高层”是相对于“低层/底层”而言的,不是说技术高级或低级。)而且有比较紧的期限限制,选delphi比较好。如果你熟悉的语言是object pascal,又不打算学复杂的c++,那么delphi几乎是唯一的选择。传统的观点是:delphi适合编写internet/intranet、表格制图、数据库操作、高级用户界面等等。visual c++适合编写设备驱动、com服务程序、科学计算、控制台(console)程序、wince的应用和一些小的工具等等。应用范围的不同要求好的程序员精通这两门语言。

  4)语言的前景和可扩充性。

  delphi是inprise的旗舰产品之一,前景应当还是比较乐观的,而且inprise已经在向linux进军了,而微软还迟迟没有动作。遗憾的是,inprise公司delphi的创始人已经跳槽到微软去主持visual j++项目了。但愿对inprise冲击不会太大。

  微软的visual c++的前景又怎样呢?visual studio 7.0就要推出了。这一版本将加强网络开发的特性。看来微软虽然被判解体,开发实力可是一点没打折扣。

  另外,虽说mfc已稍显落后,但不是说它不值得学。事实上,不学mfc就等于没学vc。利用mfc框架开发程序仍然是目前开发桌面应用的主流模式,而且还会保持相当长的时间。微软公司ceo史蒂夫·巴尔默(steve ballmer)曾说,.net流行还得等2~3年。那么,mfc至少还有2~3年的生命空间。在技术日新月异的it界,2~3年实在是很长一段时间了。好好把握吧。即使你不使用mfc框架,花点时间看一下mfc的封装机制对你熟悉c++的oop机制和windows底层功能也是很有好处的。而vcl的源代码是object pascal的,对c/c++程序员就没有这个“额外”的作用了。

[ 海韵 于 2005-05-24 00:00:00  星期二   ]  
相关文章:

网友评论
正在加载评论...


免责申明 | 版权申明 | 联系我们 | 关于
Copyright © 2001-2024 Haiyun.Net All Rights Reserved
地址:深圳市南山区南油天安工业区1栋3楼 邮编:518000
有我可以帮您的吗?QQ:12457275  
粤ICP备05017321号-1