A Brief Look at C++ 中文版 (轉)

worldblog發表於2007-12-09
A Brief Look at C++ 中文版 (轉)[@more@] 

A Brief Look at C++中文版:namespace prefix = o ns = "urn:schemas--com::office" />

Bjarne Stroustrup

AT&T Bell Laboratories

Murray Hill, New Jersey 07974

 

[原作者]:Bjarne Stroustrup (C++的設計者)

[翻譯者]:Kingofark

[Kingofark的話]:這篇文章誠然已經不新了。但我想,儘可能多的讀一讀大師們的感思,總不至於是一件壞事情罷。因此還是費力翻譯出來(Bjarne Stroustrup大師的英文文章可真是不太容易閱讀!),試圖截獲一絲助人的快樂。

 

 

本文有側重點的回答了這樣兩個問題:C++是什麼?C++在過去若干年中是如何演化發展的?有的C++應該把C++當作一個實用工具來看待。本文並無意把C++與其它語言作比較,然而我還是回答了一些特定的問題,這些問題經常被Lisp員問到。

 

1. 介紹

像所有現存的語言一樣,C++在過去若干年中不斷髮展和變化著。對我而言,C++的發展速度是極為緩慢的;但發展不可避免,它體現著C++本身在內部機制方面自然的進化,也是對千千萬萬C++使用者之使用心得的一種深思熟慮的回應。對於許多積極使用C++的人來說,這種發展慢得令人失望和喪氣。對於一些不經常使用C++的人來說,這種發展好像一種不可預見的行為,晃晃悠悠滑入了未知。而對於其他人來說,C++只是一種虛無飄渺、對其知之甚少的東西,並且伴隨著極其多的謠言圍繞著它。

不管你如何看待C++,它與第一次出現的時候相比,已經有了相當可觀的發展。舉手例子來說明:一個簡單的,其功能是對一個container排序,並計算排在Dahl和Nygaard之間的元素的個數:

template int cnt(C& v)

{

sort(c.begin(),v.end());

C::iterator d = find(v.begin(), v.end(), "Dahl");

return count(d, find(d, v.end(), "Nygaard"));

}

一個container可以看作是從begin()到end()的一系列元素之集合。在一個container中,用iterator來標識每一個元素。

只要container遵循C++標準庫的一般原則,並且其元素可以與string literals作比較,那麼這個template函式就可以如上所述正常運作。例如:

vector v; // C風格的字串vector

list lst; // C++中的string list

// ...

int i1 = cnt(v);

int i2 = cnt(lst);

其中,vector、list和string都是標準C++庫的一部分。

很自然的是,我們不必在這樣一個小小的函式里建立‘Dahl’和‘Nygaard’這樣的string值。實際上,對於任意型別的container,我們都可以生成一個通用函式,使其能對任意型別的數值在某個範圍內進行任意的操作。

顯然,這裡的風格與傳統的C程式設計風格遠不相同。然而,C++並沒有因此而喪失掉C所具有的某些重要美德:可適應性和。例如,上面程式碼中使用的C++標準庫中的演算法sort()函式,在許多相對簡單但有實際意義的例子中要比C標準庫中的qsort()函式快上好幾倍。

 

2. C++標準

C++是一種使用靜態型別機制的(statically-typed)、通用目的(general-purpose)的語言,它透過類機制和虛擬函式機制來支援面向程式設計,透過模板機制來支援範型程式設計,並透過提供底層的語言設施來支援詳細的程式設計。這個基本定義聽起來還是相當不錯的。儘管我並不認為定義中描述的那些方面可以在嚴格的意義上被證明,但是我已經看到了足夠多的事實來使我對這個定義的合理性感到滿意,這些事實包括足夠多的優秀C++程式碼,以及使用C++進行的足夠多的、成功的大規模工程。

到了1989年的時候,多種因素使得C++的標準化工作成為不可避免的一件事,被考慮到的因素包括C++使用者的數量、獨立的C++實現者以及C++工具的提供者的數目。而如果不做標準化工作,C++就會演變成一種“方言”。等到了1995年,ANSI和ISO C++標準委員會已經在對基本語言結構、標準庫的特性和在描述上的精確性等級這三個方面的把握上達到了一定層級的穩定性,從而使C++標準的草案得以釋出[Koenig,1995]。正式的標準將在1996年底或者1997年初發布。

在標準化工作的程式中,又有許多特性和庫被增加到了C++中。總的來說,標準化工作確認並增強了C++最基本的特質,使其更為完整。關於C++中的一些新特性以及產生這些特性的原因,可以在[Stroustrup;1994]中找到相關敘述。對C++一些原始特性的討論以及對一些還沒被加入C++但正在考慮的特性之討論,也可以在[Stroustrup;1994]中找到。

 

2.1 語言特性

標準C++基本上就是由《The C++ Programming Language (2nd Edition)》[Stroustrup,1991]中所描述的語言,再加上名字空間(namespace)、執行期型別(run-time type)資訊以及另外幾個次要的新特性組成的。在那些較小的改進當中,最明顯的就是對模板機制的完善。

下面是一個用C++進行物件導向程式設計的經典例子:

class Shape {

virtual void draw() = 0:

virtual void rotate(int) = 0;

// ...

};

Shape是一個抽象類;這也就是說,Shape型別只是一個介面,而沒有具體的實現。我們可以根據這個介面來定義出特定的型別。例如,下面的程式碼定義了Circle型別,它是Shape的一種:

class Circle : public Shape {

Point center;

int ;

public:

Circle(Point, int); // 建構函式(constructor)

void draw();

void rotate(int) { }

// ...

};

這樣我們就可以透過一個通用的介面來操作各種Shape型物件了。例如,下面的函式將任何Shape型向量旋轉r個角度:

void rotate_all(vector& v, int r)

{

for (int i = 0; irotate(r);

}

對於每一種特定的Shape型物件,其相應的rotate()函式被。比如,若被旋轉的是Circle物件,那麼Circle::rotate()會被呼叫。

考慮如下程式碼,它從流中讀取Shapes:

void user(istream& ss)

{

io_obj* p = get_obj(ss); // 從流中讀取物件

if (Shape* sp = dynamic_cast(p)) { // 是Shape型的嗎?

sp->draw(); // 使用Shape型物件

// ...

}

else // 噢歐:不是shape型的

throw unexpected_shape();

}

在這裡,dynamic_cast運算子用來檢查物件是否確實是Shape型的。任何一種Shape——比如Circle——都是可以的。如果碰到物件不是一種Shape的情況,就丟擲一個異常。

當然上面的例子沒有什麼實際意義。然而其中包含的技術和支援這些技術的語言特性曾被用在一些有史以來最大和最難的應用開發當中。

2.2 標準庫

缺少一個完善的標準庫一直都是C++最大的弱點之一。這個缺憾不但導致了各種不相容“基礎程式庫(Foundation Libraries)”的迅猛出現,而且還使得剛入行的C++程式設計師不得不自行設計基本庫設施,從而離完成任務的目標越來越遠。後一種情況尤為惡劣,因為設計並實現一個優秀的基本庫設施遠要比使用一個困難得多。標準庫的缺乏使得許多程式設計師在完全掌握基本的C++知識以前就被迫面對一些高階的C++特性。

標準庫所提供的設施可以分為如下幾類;

[1] 對基本的執行期語言支援(run-time language support)(比如分配、執行期型別識別等);

[2] 標準C庫(為了使其與型別系統的衝突降到最低,進行了一些微小的修改);

[3] strings和輸入輸出流(用以支援國際性的字符集和本地化操作);

[4] 一個container的(比如vector,list和map等)以及使用這些container的演算法(比如通用的遍歷、排序和結合演算法);

[5] 對數字計算的支援(複數以及向量的算術運算;類BLAS的、通用的slices;有利於處理的語意;等)。

將一個類包含在程式庫裡的主要原則有:這個類應該可能被幾乎所有的C++程式設計師(不管是新手還是專家)使用;這個類應該以一種通用的形式被提供,但與實現相同功用的、更簡單的形式相比,又不會帶來明顯的負荷;其基本用法很容易學會。總的來說,C++標準庫提供了最常用的基本資料結構以及使用這些資料結構的基本演算法。

對於程式庫中的演算法,任何container不需要經過型別等方面的轉換操作就可以使用它。這個framework——通常被稱作STL——具有可擴充套件性,使使用者可以在標準庫已提供的container和演算法的基礎上,方便的增加自己的container和演算法,並使其可以直接與標準的container和演算法共同使用。

 

3. 工具、環境和程式

標準化工作完成之後所帶來的各方面的穩定性,使得人們在程式設計環境、程式庫和工具之生產方面的工作激增。在C++領域裡,傳統的工作目標一般是要創造這樣一種C++語言,使得:即使在缺乏先進的工具和環境的情況下,人們也能在重大的工業專案中高效的使用C++。這並沒有阻礙優秀C++工具和環境的出現,但語言本身的進化已經對語言的實現和工具集的製造產生了巨大的影響。

我期待著真正優秀的程式開發環境能在未來的幾年裡被全面應用。很多曾被人們認為不可能實現的針對C++的特性現在已經在某些商業產品中被實現了。比如Sun公司的C++實現允許你在一個breakpoint處停止程式的,重寫一個函式並以新函式重新執行。這種特性已經在具有動態型別(dynamically-typed)機制的解釋型語言中存在數十年了。然而,這正是一種有趣且良好的發展,離我對程式開發環境所期望的目標又邁出了一步。在我的目標裡,程式開發環境應該兼具基於靜態型別的(statically-typed)語言之強大功能,和複雜的環境所帶來的優勢。而且這樣一個複雜的環境,應該與基於動態型別的(dynamically-typed)語言之環境相類似。

龐大的C++使用者群所帶來的益處就是大量程式庫的出現。現今已經出現了不計其數的C++程式庫,但是各個之間的差異以及標準的缺乏嚴重影響了程式庫的發展。前一個問題引起了對程式庫的不必要的分段(segmentation),並導致一些專門用於解決跨平臺問題的程式庫出現。後一個問題迫使開發者一遍又一遍的重複設計諸如string和list這樣的基本設施。儘管仍需要多年的時間才能把這些問題完全從C++系統中解決掉,我們現在就已經有了替代方案,可以使我們把心思放到更重要也更有趣的方面上去。

垃圾自動收集機制(automatic garbage collection)也許對於C和Lisp這兩種語言來說,都是格格不入的。Lisp語言堅持:記憶體管理太重要了,所以絕不能留給使用者自己管理。而C語言則堅持:記憶體管理太重要了,所以絕不能讓系統來管理。C++採取了一種折衷方案。C++允許使用垃圾自動收集機制,但又不強制使用它。從傳統的觀點來看,這即意味著C++不使用垃圾自動收集機制,但現在無論是商業的還是免費開放的垃圾收集器(garbage collector)之C++實現,都有其實際的用途。這些垃圾收集器的之良好是值得期待的,尤其比我數年來聽到對其進行的悲觀預言要好得多。甚至是在不使用垃圾收集器的時候,設計良好的C++程式因記憶體管理而遇到的麻煩也比傳統的C程式少得多。在C++中,記憶體管理通常被封裝在使用者自定義的型別中,使用者根本就不需要直接對記憶體進行分配和去配。特別是諸如string、vector和list這樣的標準container,都有其自己的記憶體管理機制,並提供大小可變的資料結構。

 

4. 程式設計風格

C++是一種支援多種paradigm的語言。換句話說,C++語言被設計成能支援多種程式設計風格的形式。沒有哪個語言能同時支援所有種類的程式設計風格。然而在一個語言的framework中卻可以同時支援多種風格。這樣做,我們就可以透過共享通用型別系統和通用工具集等設施的方法來得到頗為豐厚的收益。這些技術優勢可以體現在一些重要的實際收效中,比如可以提供groups,以滿足在共享一門語言時所提出的各種不盡相同的需要,這就比根據不同需要而特意實現幾種特定的語言要划算得多。

對於C++新手,C++還支援傳統的C程式設計風格。其它的程式設計風格則強調使用類、抽象類、類層次和模板等機制,以便直接的、清晰的、具象的體現各種概念以及各概念之間的關係。例如,本文第1節使用了範型程式設計技術,第2.1節又演示了抽象類和類層次的使用。

在C++程式設計風格(比如[Kornig,1995b]一書)和設計(比如[Gamma,1994]一書)方面所做的許多工作都著重於尋求一種方法,藉以表達出來自各種語言和系統中的觀點(a),從而讓那些編寫大型系統的C++程式設計師能夠高效率、高效益的運用這些觀點。其關鍵就在於高效的運用C++中的這個具有可適應性和可擴充套件性的靜態型別系統(static type system)。

 

5. 致謝

感謝Craig Knoblock邀請我撰寫本文。

 

6. 參考

[Gamma,1994] Gamma, et.al.: Design Patterns. Addison Wesley. 1994. ISBN 0-201-63361-2.

[Koenig,1995] Andrew Koenig (editor): The Working Papers for the ANSI-X3J16 /ISO-SC22-WG21 C++ standards committee.

[Koenig,1995b] Andrew Koenig and Bjarne Stroustrup: Foundations for Native C++ Styles. Software– Practice & Experience. 1995.

[Stepanov,1994] Alexander Stepanov and Meng Lee: The Standard Template Library. ISO Programming language C++ project. Doc No: X3J16/94-0095, WG21/N0482.

[Stroustrup,1991] Bjarne Stroustrup: The C++ Programming Language (2nd Edition) Addison Wesley,ISBN 0-201-53992-6. June 1991.

[Stroustrup,1994] Bjarne Stroustrup: The Design and Evolution of C++ Addison Wesley, ISBN 0-201-54330-3. March 1994.


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-990010/,如需轉載,請註明出處,否則將追究法律責任。

相關文章