20世紀80年代末到90年代初,X Window、Mac OS、Windows等窗口環境的先后出現為程序設計提出了新的課題,而C++語言兼顧面向對象和傳統開發方法的特性無疑使其成為了窗口環境下編程語言的最佳選擇。一批基于C++語言的窗口框架不僅在商業上取得了成功,也在很大程度上改變了C++語言本身的風格特點。 最早在窗口開發中贏得大多數程序員青睞的C++框架是Borland公司于1992年內置在Borland C++ 3.1中的OWL(Object Windows Library)框架庫。下面這段代碼取自Borland C++ 3.1的示例程序:class TGDIDemoWindow : public TMDIFrame
Stroustrup于1988年首次公布了與模板(template)有關的語法設計。毫無疑問,這是一項對現代C++的語言風格影響最大的技術改進。模板的概念來自Clu語言,并綜合了Smalltalk和Ada語言中相關技術的優點。1991年后,包含模板機制的開發環境(DEC C++、IBM C++、Borland C++等)陸續問世。但直到1995年STL(Standard Template Library)模板庫逐漸發展成熟以后,模板技術才在程序員中迅速普及開來。 下面的例子取自SGI STL的示例代碼,它基本反映了使用模板技術后C++代碼的整體風格:template <class InputIterator, class T> InputIterator find(InputIterator first, InputIterator last, const T& value) { while (first != last && *first != value) ++first; return first; } 在這樣的C++代碼中,除了少數幾個要害字和操作符以外,我們幾乎找不到多少C語言的痕跡了。模板技術兼顧了類型安全和編碼靈活性的雙重需求,但它同時也為C++語言引入了一種更加精妙但也較難理解(相對于沒有模板的代碼而言)的代碼風格。許多傳統的C語言擁護者討厭這種風格的代碼,但更多的新生代程序員對其鐘愛有加。1998年,在ANSI/ISO標準化委員會的支持下,STL被作為標準C++庫(Standard C++ Library)的一部分收入了C++國際標準之中。今天,以模板、異常等現代C++技術為代表的語言風格也已在事實上成為了C++世界的“官方風格”。 更多內容請看C/C++技術專題專題,或
5. ATL——COM時代的另類C++
除了STL模板庫之外,還有一個與模板風格相關的例子。下面的代碼片斷取自Visual C++自動生成的ATL控件工程: class ATL_NO_VTABLE CMyATLObj :
public IMyATLObj, public ipersistStreamInitImpl <CMyATLObj>, public IOleControlImpl<CMyATLObj>, public IOleObjectImpl<CMyATLObj>, public IoleInPlaceActiveObjectImpl <CMyATLObj>, public IViewObjectExImpl<CMyATLObj>, public IoleInPlaceObjectWindowlessImpl <CMyATLObj>, public IPersistStorageImpl<CMyATLObj>, public IspecifyPropertyPagesImpl <CMyATLObj>, public IQuickActivateImpl<CMyATLObj>, public IDataObjectImpl<CMyATLObj>, public IProvideClassInfo2Impl <&__uuidof(CMyATLObj), NULL>, public CComControl<CMyATLObj> ...... 注重控件類CMyATLObj的代碼,CMyATLObj類居然是從N個接口類和控件類中派生出來的,類的聲明語句中隨處可見模板的身影——這就是Microsoft為我們設計的別具一格的ATL風格的代碼了。之所以要不惜代價地大量使用模板、多重繼續等語言特性,這主要為了適應COM、OLE、ActiveX等在架構上本來就相對復雜的技術體系。但這樣一來,使用ATL的代碼在所有C++代碼中,就擁有了一副異乎平常的長相了:到處都是尖括號,到處都是以“I”打頭的標識符,甚至還有多重尖括號的嵌套……假如要求一個剛學會C++語言的程序員馬上讀懂一大段ATL代碼,我想,用不了幾分鐘,他就會被代碼中那些晦澀、離奇的語言風格折磨得精神崩潰了。
說到標準C++語言風格,有必要給大家看一段非常古怪但也非常有趣的代碼。你看得懂下面這段C++代碼嗎?它是真正的C++代碼嗎? %:include <iostream> using namespace std; %:define MAX 5 void main() <% int m<:MAX:>; int i = 1; for (i = 0; i < MAX; i++) <% m<:i:> = i; if (i not_eq 3 and i < 5) cout << i << endl; %> %> 這是我自己編寫的一段代碼。你也許無法在Visual C++環境下運行它,但它的語法的確符合1998年C++標準的規定。在GNU C++環境下,我曾成功地將其編譯為可執行程序。 簡單說來,這段風格詭異的C++代碼其實是根據C++標準中關于可替換標記(Alternative Tokens)的規定而編寫的。該規定的設計初衷是要適應歐洲某些國家的標準字符集缺少“{”、“#”等標點符號(非凡是在一些傳統的終端設備上)的現狀。嚴格地講,這算不得一種真正的語言風格,但類似的規定的確體現了ANSI/ISO委員會在語言設計上兼容并包的寬廣胸襟。
8. C++Builder——Borland的復興之路
Borland公司在發布了Borland C++ 3.1之后,就因為不思進取而將C++開發工具的市場拱手讓給了Microsoft[4]。在經歷了Borland C++ 4.0、4.5和5.0等版本的失敗后,1997年,Borland推出了全新的C++開發工具C++Builder。這個在市場上為Borland挽回了顏面的產品不但在界面風格上與Borland的支柱產品Delphi別無二致,甚至還在產品內部直接照搬了Delphi的VCL(Visual Component Library)庫。結果,使用C++Builder開發的代碼天生就受到了Delphi風格的傳染,長相酷似Pascal語言了(以下代碼取自C++Builder 6.0的示例代碼):class TFormClrDlg : public TForm { published: // IDE-managed Components TColorDialog *ColorDialog; TButton *Button; TPanel *Panel1; void fastcall ButtonClick(TObject *Sender); private: // User declarations public: // User declarations virtual fastcall TFormClrDlg(TComponent* Owner); }; 說實話,盡管C++Builder在市場上的表現不錯,但我還是不喜歡Borland將C++語言與Delphi中的Object Pascal語言刻意混淆的做法。也許在Borland這種做法的背后有提高產品通用性、縮短產品開發周期等體面的理由,但使用C++Builder開發出的代碼在外表上已經離標準C++風格越來越遠了。 值得注重的是,Borland于2003年推出了其下一代C++開發工具 ——C++BuilderX。讓人哭笑不得的是,這一次Borland居然將C++開發環境構筑在了用Java語言實現的PrimeTime平臺上,這多少將C++語言推向了一種極為尷尬的處境。不過,C++BuilderX也為我們帶來了一些好消息:在后續的版本中,C++BuilderX將集成vxWindows框架庫[5],在這種框架下開發的C++代碼顯然要比使用VCL的代碼具備更多的標準C++風格。
9. Visual C++ .NET——革命還是叛逆?
Microsoft將C++引入.NET環境的舉動其實比Borland還要激進。單從風格上說,使用Visual C++ .NET開發的代碼可能兼具MFC、ATL、標準C++、.NET托管代碼等多種不同的風格。其中,對C++語言本身影響最大的,當然要數.NET托管代碼為C++注入的若干新鮮血液了:#using <mscorlib.dll>
using namespace System; using namespace System::Reflection; using namespace System::Security::Permissions;
語言風格的變遷從一個側面反映了技術思想和產業需求的嬗變規律。從1979年Stroustrup完成第一個Cpre預處理程序算起,C++語言來到這個世界上已經快滿25個年頭了。這是一種在實踐中誕生、成長和發展起來的語言。也許,Stroustrup從一開始就壓根兒也沒想把它設計成像Smalltalk那樣純粹的面向對象語言。開放性、高效率、兼容性和擴展性的需求將C++語言塑造成了一種典型的多模式(Multiparadigm)語言。無論是C++早期對Simula語言的繼續,還是后來對Smalltalk、Ada、Clu等語言的借鑒,無論是ANSI/ISO標準風格的迅速普及,還是Visual C++ .NET在技術創新上的不懈努力,所有這些歷史變遷都說明,C++在風格上的多樣性主要源自C++語言本身“海納百川”的胸襟和氣概。 5年以后,當C++步入而立之年的時候,它會給我們帶來新的驚喜嗎?我們還會看到更加新奇的C++語言風格嗎?也許,沒有誰能給出準確的答案。但作為程序員,我們至少應該知道:無論面對什么樣的軟件需求,無論使用什么樣的思維方式,C++語言都賦予了我們選擇語言風格的最大自由;當我們真正理解了C++語言的精神實質之后,這種自由也必將成為所有優秀軟件和優雅代碼的堅實基礎。
參考文獻
[1] 劉勰. 文心雕龍·序志. [2] Stroustrup B. C++ 語言的設計和演化. 北京: 機械工業出版社, 2002 [3] Stroustrup B. Learning Standard C++ as a New Language. C/C++ Users Journal. pp 43-54. May 1999. [4] 李維. Borland 傳奇. 北京: 電子工業出版社, 2003 [5] 李維. 細說Borland C++BuilderX. 程序員. 2003.11 更多內容請看C/C++技術專題專題,或