引言
“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開發更加如此。