開發(fā)工具大比拼之VisualC++VSDelphi

字號:

引言
    "Visual C++與Delphi之比較"最近在CSDN的論壇上的討論非?;馃?,本文將以一個程序員的角度,從技術(shù)水平、功能、性能、易用性、穩(wěn)定性、發(fā)展歷程和前景等方面,以Visual C++6和Delphi5為代表,盡可能客觀地比較介紹Visual C++和Delphi這兩大主流開發(fā)工具的優(yōu)缺點,其中將涉及到語言、應用框架、控件、編譯和連接、集成界面、調(diào)試、COM、數(shù)據(jù)庫開發(fā)等。本文還將對如何選擇使用這兩個開發(fā)工具提出一些建議。
    值得一提的是,由于C++Builder與Delphi同為Inprise公司產(chǎn)品,它們除了使用的語言不同,其余特性幾乎都相同。因此本文對C++Builder程序員和學習者也有參考價值。
    語言:存在即是合理
    首先聲明常被混淆的一點:VC和Delphi本身不是語言,而是開發(fā)平臺。它們所用的語言分別是略作擴展的C/C++和Object Pascal。我在網(wǎng)上??吹接腥藛枒搶WC/C++還是VC,這個問題很好回答:如果你學VC你就必須得學C/C++,或者說你學會了VC也就學會了C/C++了。
    言歸正傳,我們來比較一下C++和Object Pascal的優(yōu)缺點。有人認為Object Pascal是"玩具語言",C++才是"專業(yè)語言",這是不對的。單從語言本身看,Object Pascal與C++屬同一重量級。它們都是完全支持面向?qū)ο蟮恼Z言,都扎根于"歷史悠久"的面向過程的語言。C++是由C發(fā)展而來的,Object Pascal由Pascal進化而來。它們都有很強的靈活性,都有自己的特長和不足。比如說,Object Pascal不支持多重繼承、模板、操作符重載、內(nèi)聯(lián)函數(shù)定義、預處理、宏、全局靜態(tài)類變量、嵌套類定義,等等,而這些都是C++支持的。但同樣地C++也不支持Object Pascal的虛構(gòu)造函數(shù)、過程嵌套、內(nèi)置集合類型、內(nèi)置字符串類型、"finally"構(gòu)造等等,在RTTI方面Object Pascal也比C++做得好。但這些并不重要,因為可以通過其它方式達到同樣的目的,比如C++可以通過類擴展支持集合、字符串,Object Pascal可以通過"interface"多重繼承,等等。關(guān)鍵是二者都可以很好地完成你手頭的任務,這就夠了。
    但是,僅僅比較語言本身是不夠的,還得看它們的被接受和流行程度,學習曲線,發(fā)展前途,可移植性等,以及,很重要但常常被忽略的一點:與開發(fā)環(huán)境(指VC與Delphi)及其應用框架的"磨合"程度。
    VC和Delphi作為開發(fā)平臺,很重要的一點就是提供了一個"無所不包"的應用框架:VC的MFC和Delphi的VCL。MFC是用C++寫的,VCL是用Object Pascal寫的。當然,我們都知道,C++的使用范圍比Object Pascal廣得多,移植性也好得多。這本來是優(yōu)點,但很有意思的是,正因為如此,微軟寫MFC時必須考慮限度減少對語言本身的改動,而把功夫下在源代碼級,以便能盡可能支持ANSI等標準,結(jié)果導致MFC的封裝復雜而不直觀。(尤其是它對消息的封裝,下文還會提到)。太多的宏定義和含義模糊且自動生成、不得改動的注釋使MFC乃至VC讓很多新手望而生畏,不敢"下水"深入學習。而Object Pascal幾乎是Inprise"專用"的,不必考慮"標準"問題,因此Inprise寫VCL時就把全部精力放在了結(jié)構(gòu)與性能上,結(jié)果語言與框架的磨合程度非常好。VCL框架的結(jié)構(gòu)清晰,VCL代碼的可讀性非常好。許多人說Delphi比較容易上手,也是這個緣故。天下沒有白吃的午餐。你要工業(yè)標準嗎?你要可移植性嗎(關(guān)于可移植性和兼容性,下文會詳細比較)?那么請面對MFC的"天書"級代碼吧。
    編譯和連接:The Need For Speed
    不同的語言帶來的另一個不同是,編譯和連接的速度的不同,以及執(zhí)行速度的不同。Delphi的編譯和連接速度,毫不夸張地說,比VC快幾十倍。即使把VC的Incremental Link選項打開,Delphi的編譯和連接速度仍比VC快好幾倍。并不是說微軟的編譯器不行,這是由C++的復雜性決定的。模板的處理、預處理和宏的展開都是很費時的。前文不是提到Object Pascal沒有模板、預處理和宏嗎?這本來是缺點,但帶來的一個好處就是編譯速度極快。至于編譯完的二進制代碼,在打開相同的優(yōu)化選項的情況下,Delphi和VC執(zhí)行速度并沒有太大的差別。
    為了克服編譯的速度問題,C++編譯器一般需要增強的連接器和預處理機制。但是預處理機制仍然存在若干問題:1)程序調(diào)試的斷點行可能和代碼行不同;2)沒有將最新的代碼信息綜合進去;3)容易產(chǎn)生錯誤的邏輯;4)因為讀錯文件頭而很容易產(chǎn)生類似"Unexpected End of File"的錯誤。
    兩個編譯器有個共同點是都能識別無用的"死"代碼,比如一個沒有用的函數(shù)等等。編譯后的程序?qū)⒉话@些多余的信息。Delphi在這方面作得更加出色。它可以讓你在編輯器中可視化地提示出那行代碼是"活"的、那行代碼是"死"的。這樣你就能整理出最精簡的代碼。Delphi在編譯后將在左邊顯示一個小藍點表示這行代碼是"活"的。Visual C++做不到這點。
    Delphi編譯后可執(zhí)行文件至少有200K(如果不使用VCL,僅僅使用WinAPI,文件的大小將大大縮?。┑荲isual C++編程使用MFC編譯后的可執(zhí)行文件通常只有幾十K,主要是因為微軟已經(jīng)將系統(tǒng)運行庫包含在Windows系統(tǒng)了(Borland公司曾經(jīng)和微軟協(xié)商這個接口,但是微軟利用操作系統(tǒng)的優(yōu)勢不愿意公開)。同樣道理,使用BDE開發(fā)的的數(shù)據(jù)庫程序必須附帶3-5M的額外系統(tǒng)文件,也是非常不協(xié)調(diào)的。
    非常有趣的是,Delphi能夠使用由C++ Builder創(chuàng)建的的OBJ文件,但是使用上受很大的局限性。
    最后,Visual C++的編譯和連接時的錯誤信息比Delphi要詳細和具體的多。特別是使用ATL開發(fā)更加如此。
    應用框架:MFC?有KFC流行嗎?
    應用程序框架(Application Frame),有時也稱為對象框架。Visual C++采用的框架是MFC。MFC不僅僅是人們通常理解的一個類庫(同樣,Delphi的VCL也不僅僅是一個控件庫,盡管它的名字叫"可視控件庫")。你如果選擇了MFC,也就選擇了一種程序結(jié)構(gòu),一種編程風格。MFC早在Windows 3.x的時代就出現(xiàn)了,那時的Visual C++還是16位的。經(jīng)過這些年的不斷補充和完善,MFC已經(jīng)十分成熟。但由于原型出現(xiàn)得比較早,MFC相比于VCL落后了一個時代。盡管微軟對MFC的更新沒有停止,我也經(jīng)常讀到"只要Windows不過時,MFC就不會過時"之類觀點的文章,但就象Inprise(原Borland)的OWL框架的淡出一樣,MFC的淡出也是早晚的事。其實MFC是和OWL同一個時代的產(chǎn)物。OWL已經(jīng)不在了,MFC怎能不"居安思危"呢?如果MFC青春永駐,微軟的開發(fā)人員也不會"私自"開發(fā)出基于ATL的WTL呀。當然,WTL的地位不能和MFC比,它并不是微軟官方支持的框架,封裝的功能也相當有限。但至少也反襯出了MFC存在的不足。