在1983年12月Bjarne Stroustrup采納Rick Mascitti的建議,將其發明的新語言命名為“C++”之前,人們一直用“帶類的C(C with Classes)”來稱呼這種脫胎于C語言的,帶有數據抽象機制的“方言”。雖然帶類的C在本質上僅僅是一種可以被預處理程序CPRe轉換為傳統C語言代碼(這類似于我們在Oracle中見到的Pro*C語言的預處理過程)的擴展性語言,但它的確在風格上奠定了后來所有C++代碼的基礎。
就在Borland C++ 3.1統治市場兩年以后,Microsoft憑借其當仁不讓的霸氣和聞名的Visual C++系列產品逐漸奪回了Windows開發工具市場的主導權。與Borland不同的是,Visual C++中的MFC(Microsoft Foundation Class)框架庫沒有向OWL那樣肆意篡改C++的語法,而是采用了下面這樣的方式來實現消息映射(代碼取自MSDN示例程序):
// Example for BEGIN_MESSAGE_MAP BEGIN_MESSAGE_MAP( CMyWindow, CFrameWnd ) ON_WM_PAINT() ON_COMMAND( IDM_ABOUT, OnAbout ) END_MESSAGE_MAP( ) 事實上,用MFC框架編寫的C++代碼在大量使用宏定義等預編譯指令的同時,還把WIN32平臺下常見的匈牙利風格(有關標識符大小寫和前綴的書寫規范)發揮到了極限。這一點用不著我多費口舌,許多程序員僅從代碼的大小寫特征上就能百分之百地確定代碼中是否使用了MFC框架。
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代碼,我想,用不了幾分鐘,他就會被代碼中那些晦澀、離奇的語言風格折磨得精神崩潰了。
%: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++環境下,我曾成功地將其編譯為可執行程序。
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++風格越來越遠了。
語言風格的變遷從一個側面反映了技術思想和產業需求的嬗變規律。從1979年Stroustrup完成第一個Cpre預處理程序算起,C++語言來到這個世界上已經快滿25個年頭了。這是一種在實踐中誕生、成長和發展起來的語言。也許,Stroustrup從一開始就壓根兒也沒想把它設計成像Smalltalk那樣純粹的面向對象語言。開放性、高效率、兼容性和擴展性的需求將C++語言塑造成了一種典型的多模式(Multiparadigm)語言。無論是C++早期對Simula語言的繼續,還是后來對Smalltalk、Ada、Clu等語言的借鑒,無論是ANSI/ISO標準風格的迅速普及,還是Visual C++ .NET在技術創新上的不懈努力,所有這些歷史變遷都說明,C++在風格上的多樣性主要源自C++語言本身“海納百川”的胸襟和氣概。