delphi与vc的比较
~v~
“Visual C++和Delphi的比较”最近在CSDN论坛上引起了热烈的讨论。本文将以Visual C++6和Delphi5为代表,从技术水平、功能、性能、易用性、稳定性和前景等方面,客观地比较和介绍Visual C++和Delphi的优缺点,这将涉及语言、应用框架、控件等方面。本文还将对如何选择和使用这两种开发工具给出一些建议。
值得一提的是,由于C++Builder和Delphi都是InEnterprise的产品,所以除了语言不同之外,它们几乎具有相同的特征。因此,本文对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++也不支持虚构造函数、过程嵌套、内置集合类型、内置字符串类型、“finally”构造等。在RTTI,Object Pascal比C++做得更好。但这些都不重要,因为同样的目标可以通过其他方式实现,比如C++可以通过类扩展支持集合和字符串,Object Pascal可以通过“inte***ce”多次继承等等。关键是两个人都能很好的完成手头的任务,这就足够了。
但仅仅比较语言本身是不够的,还要看其接受度和普及度、学习曲线、发展前景、可移植性等。,以及一个很重要但经常被忽视的点:与开发环境(指VC和Delphi)及其应用框架的“磨合”程度。
VC和Delphi作为开发平台,提供了一个包罗万象的应用框架:VC的MFC和Delphi的VCL。MFC是用C++写的,VCL是用Object Pascal写的。当然,我们都知道C++的用途比Object Pascal广得多,可移植性也好得多。这本来是一个优势,但很有意思的是,正因为如此,微软在编写MFC时必须考虑尽量减少对语言本身的改动,为了尽可能支持ANSI等标准,把重点放在源代码层面,导致MFC的包装复杂而直观。(尤其是它对消息的封装,下面会提到)。太多含义模糊的宏定义和注释是自动生成的,无法更改,这让很多新手对MFC甚至VC望而生畏,不敢“下水”深入学习。Object Pascal几乎是InEnterprise“专用”的,不需要考虑“标准”的问题。所以InEnterprise在写《VCL》的时候把所有的精力都放在了结构和表现上,使得语言和框架的融合度非常好。VCL框架结构清晰,VCL代码可读性很好。很多人说Delphi好用,也是这个原因。天下没有免费的午餐。你想要工业标准吗?要不要便携性(下面会详细比较便携性和兼容性)?那么请面对MFC的“天书”代码。
编译和连接:对速度的需求
不同语言带来的另一个区别是编译和连接的速度不同,执行的速度也不同。毫不夸张的说,Delphi的编译和连接速度比VC快几十倍。即使开启了VC的增量链接选项,Delphi的编译和连接速度还是比VC快好几倍。不是微软的编译器不行,是C++的复杂程度决定的。模板处理、预处理和宏扩展都很耗时。前面不是提到Object Pascal没有模板,没有预处理,没有宏吗?这是一个缺点,但一个优点是编译速度极快。至于编译后的二进制代码,在开启相同优化选项的情况下,Delphi和VC的执行速度并没有太大差别。
为了克服编译的速度问题,C++编译器一般需要增强的连接器和预处理机制。但预处理机制还存在一些问题:1)程序调试的断点行可能与代码行不同;2)没有整合最新的代码信息;3)易错逻辑;4)由于读取错误的文件头,容易出现“文件意外结束”之类的错误。
两个编译器的共同点是,它们可以识别无用的“死”代码,比如一个无用的函数等等。编译后的程序不会包含这些冗余信息。德尔福在这方面做的比较好。它允许您在编辑器中直观地指示哪一行代码是“活的”,哪一行代码是“死的”。这样你就可以整理出最精简的代码。Delphi在编译后会在左边显示一个小蓝点,表示这一行代码是“活的”。Visual C++做不到这一点。
Delphi编译的可执行文件至少200K(如果不使用VCL,只使用WinAPI,文件大小会大大减小),但Visual C++编程中MFC编译的可执行文件通常只有几十K,主要是因为微软已经将系统运行时包含在Windows系统中(Borland公司曾经与微软协商过这个接口,但微软不愿意利用操作系统的优势将其公开)。同样,BDE开发的数据库程序,必须附带3-5M的额外系统文件,也是非常不协调的。
很有意思的是,Delphi可以使用C++ Builder创建的OBJ文件,但是使用受到很大限制。
最后,编译连接Visual C++时的错误信息比Delphi详细具体得多。尤其是使用ATL开发。
应用框架:MFC?肯德基受欢迎吗?
应用程序框架,有时称为对象框架。Visual C++采用的框架是MFC。MFC不仅仅是人们通常理解的类库(同样,Delphi的VCL也不仅仅是一个控件库,虽然它的名字是“可视化控件库”)。如果你选择了MFC,你也选择了一个程序结构和一种编程风格。MFC早在Windows 3.x就出现了,当时Visual C++是16。经过多年的不断补充和完善,MFC已经非常成熟。然而,由于原型的早期出现,MFC落后于VCL一个时代。虽然微软对MFC的更新一直没有停止,我也经常看到“只要Windows过时,MFC就不会过时”之类的文章,但是就像InEnterprise(原Borland)的OWL框架淡出一样,MFC迟早会淡出。其实MFC和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提供了简化多线程操作的类,但只有工作线程相对容易使用。如果线程必须处理接口,事情就变得麻烦了,因为除了应用程序的主线程之外,没有线程可以访问任何可视VCL组件。您必须使用Synchronize方法等待主线程处理它的消息,然后访问主线程中的VCL组件。另一方面,MFC没有这样的限制。
稳定和完美:VC是老大哥。
VC比Delphi更加稳定和完善。VC的发展历史比Delphi长,微软的整体实力比InEnterprise强。MFC,VC的框架,经历了这么多年的发展和完善,功能非常全面稳定,bug很少。其中,你遇到的bug可能更少。第三方有专门的工具来帮助你避免这些错误。这种规模的类库做到这一点并不容易。不要小看这个,很多职业程序员都是为此选择VC的。因为虽然VCL比MFC更抽象,封装层次更高,但是它带来的开发效率的提升对于专家来说是有限的。如果你遇到一个奇怪的问题,并且调试了很长时间,你发现不是你的代码错了,而是VCL的一个错误。你怎么想呢?虽然不太可能遇到这样的问题,但对VCL的形象影响很大。Delphi的IDE占用资源太多,启动速度太慢,和一些显卡驱动冲突,VCL有bug,调试器不够健壮,对不稳定的第三方控件没有保护措施...问题很多,Delphi在这方面不如VC。我希望登上一层楼梯就能到达我的企业。对了,我们在网上看到有人对Delphi的不稳定性评价很高,说几分钟就有20多个非法操作。Delphi不如Visual C++稳定,但也不尽然。我估计我朋友的Delphi安装了一些有问题的第三方控件,导致Delphi经常出错。你为什么不试着去掉那些控制?
便携性:立足现实,放眼未来。
InEnterprise正在开发Delphi的Linux版本,代号Kylix。或许通过Kylix,可以把用VCL框架编写的Windows程序移植到Linux上。但这只是可能。因为目前InEnterprise的兼容性还没有做好。较低版本的Delphi不能使用较高版本的VCL组件,较高版本的Delphi不能使用较低版本的VCL组件。令人愤慨的是,我们很少看到非二进制兼容的软件。如果Windows 98不能运行95程序,Windows 95不能运行3.x程序,Win 3.x不能运行DOS程序,你还会用Windows吗?如果Windows 95的程序要重新编译才能在98下运行,98会卖得这么好吗?“兄弟”C++Builder和Delphi不能互相使用对方的组件,甚至同一个VCL库的文件名也不一样。因此,一个组件拥有d 1/D2/D3/D4/D5/C 1/C3/C4/C5的不同版本是很常见的,而且可能会随着Delphi和C++Builder的升级而增加。希望InEnterprise能先解决兄弟们的兼容性问题。微软的VC就没有这些问题。MFC1.0的程序也可以在VC6.0下毫无障碍的编译通过。
集成接口:宏观和微观
总的来说,VC的集成界面不如Delphi。Delphi只用一个对象检查器就能比较VC的一堆向导,更不用说代码浏览器,ToDo列表等等了。但是从一个小的点上,可以看出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控件还可以方便地构造一个基于数据库的网页,并通过HTML来管理Web数据库。Visual C++主要通过ADO和OLEDB访问数据,很多ActiveX控件也可以添加数据库功能。但是没有Paradox这样的桌面数据库,Access的相对功能就太弱了。也许SQL Server是个不错的选择。
COM:新技术的力量
COM是组件对象模型的缩写。它是OLE和ActiveX技术的基础。COM定义了一组API和一个二进制标准,使得不同编程语言和平台中的独立对象能够相互通信。
COM是微软制定的行业标准。但是Delphi也为COM提供了强大的语言支持。支持接口、变量和宽字符串函数。COM的这些包确实比C++方便。比如用C++(没有类框架)编程COM时,variant被定义为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(现在有人知道这个产品吗?)和微软C/C++从来都不是主流。但是Borland C++流行了多少年了?很快就被新崛起的微软Visual C/C++淹没了。于是Enterprise(原Borland)拿起Turbo Pascal和Borland Pascal(其实Borland的成名作是第一个Pascal编译器)的荣耀,全力推出了Delphi。Delphi刚推出的时候被称为VB杀手,但是VB依然活得好好的。毕竟微软是从Basic起家的,VB没那么好打。Inprise想了想,没有和VB争论。它用C++语言使用Delphi IDE和VCL,推出C++Builder,冲击Visual C++的市场。C++Builder似乎是一个很好的妥协?再想想!Delphi有C++Builder的所有优点,但C++Builder不一定有Delphi的优点。比如C++Builder的编译速度比VC慢,那怎么比得上Delphi?而且因为VCL是用对象Pascal写的,C++语言和VCL不能很好地一起工作。C++Builder的bug比Delphi多,甚至样本代码也有错误。VCL的部分功能无法使用,需要通过嵌入pascal代码来访问。C++Builder中可用的第三方控件比Delphi少得多。
唉,黄金无价。微软和InEnterprise谁会笑到最后?
鱼和熊掌:艰难的选择
选择开发工具取决于许多不同的因素,每个人都可能因为某种缺陷而放弃学习或使用一种语言。任何一个程序员都希望自己喜欢的工具能够达到理想的状态。通过上面不完美的对比,我想每个人都有自己的看法。我们认为,影响人们选择开发语言的因素主要包括:
1)哪种语言更容易学?
学习语言需要大量的时间和精力。开发方案的开发成本是一个值得考虑的现实。一个熟练的Delphi程序员和一个熟练的VC程序员的工作效率是一样的。然而,要成为一名熟练的程序员,你必须快速掌握一门语言的技能。可惜目前熟练的Visual C++程序员是十分之一。相对来说,Delphi更适合初学者。
2)哪种语言的可继承代码更多?
语言代码的可重用性是加速开发效率的一个明显方面。从早期的工艺、功能到现在的组件技术,我们都在朝着这个目标奋斗。这两种语言对代码重用的理解是不同的。Delphi主要通过VCL控件实现代码复用,而Visual C++实现起来更复杂。
3)语言本身的性质。
就技术(主要是应用框架)而言,Delphi目前领先于Visual C++。但缺乏稳定性和稳健性让我“说我爱你不容易”提高。虽然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服务程序、科学计算、控制台程序、WinCE应用和一些小工具。不同的应用需要优秀的程序员同时精通两种语言。
4)语言的前景和扩展性。
德尔福是InEnterprise的旗舰产品之一,前景应该是乐观的。另外,InEnterprise一直在向Linux进军,但微软还没有动作。可惜的是,Delphi的创始人InEnterprise已经跳槽到微软去托管Visual J++和C#项目了。希望对InEnterprise的影响不会太大。
微软的Visual C++前景怎么样?Visual Studio 7.0即将问世。这个版本将加强网络开发的特点。看起来微软虽然被判解体,但开发实力丝毫不打折扣。
另外,MFC虽然有点落后,但不代表不值得学习。其实不学MFC就是不学VC。使用MFC框架开发程序仍然是目前开发桌面应用的主流模式,而且还会保持很长一段时间。微软首席执行官史蒂夫·鲍尔默曾经说过。NET将不得不等待2-3年。那么,MFC至少还有2-3年的寿命。在技术日新月异的IT领域,2-3年真的是一段很长的时间。好好利用。即使不使用MFC框架,熟悉一下C++的OOP机制和Windows的底层函数,看一看MFC的封装机制也是有好处的。VCL的源代码是Object Pascal,对C/C++程序员没有“额外”的影响。