C++ STL簡介 (轉)

worldblog發表於2008-01-06
C++ STL簡介 (轉)[@more@]一、STL簡介

STL(Standard Template Library,標準模板庫)是惠普實驗室開發的一系列的統稱。它是由Alexander Stepanov、Meng Lee和David R Musser在惠普實驗室工作時所開發出來的。現在雖說它主要出現在C++中,但在被引入C++之前該技術就已經存在了很長的一段時間。

STL的程式碼從廣義上講分為三類:algorithm(演算法)、container(容器)和iterator(迭代器),幾乎所有的程式碼都採用了模板類和模版的方式,這相比於傳統的由函式和類組成的庫來說提供了更好的程式碼重用機會。在C++標準中,STL被組織為下面的13個頭:。以下筆者就簡單介紹一下STL各個部分的主要特點。

二、演算法

大家都能取得的一個共識是函式庫對資料型別的選擇對其可重用性起著至關重要的作用。舉例來說,一個求方根的函式,在使用浮點數作為其引數型別的情況下的可重用性肯定比使用整型作為它的引數類性要高。而C++透過模板的機制允許推遲對某些型別的選擇,直到真正想使用模板或者說對模板進行特化的時候,STL就利用了這一點提供了相當多的有用演算法。它是在一個有效的中完成這些演算法的——你可以將所有的型別劃分為少數的幾類,然後就可以在模版的引數中使用一種型別替換掉同一種類中的其他型別。

STL提供了大約100個實現演算法的模版函式,比如演算法for_each將為指定序列中的每一個元素指定的函式,stable_sort以你所指定的規則對序列進行穩定性排序等等。這樣一來,只要我們熟悉了STL之後,許多程式碼可以被大大的化簡,只需要透過呼叫一兩個演算法模板,就可以完成所需要的功能並大大地提升。

演算法部分主要由標頭檔案組成。是所有STL標頭檔案中最大的一個(儘管它很好理解),它是由一大堆模版函式組成的,可以認為每個函式在很大程度上都是獨立的,其中常用到的功能範圍涉及到比較、、查詢、遍歷操作、複製、修改、移除、反轉、排序、合併等等。體積很小,只包括幾個在序列上面進行簡單數學運算的模板函式,包括加法和乘法在序列上的一些操作。中則定義了一些模板類,用以宣告函式。

三、容器

在實際的開發過程中,資料結構本身的重要性不會遜於操作於資料結構的演算法的重要性,當中存在著對時間要求很高的部分時,資料結構的選擇就顯得更加重要。

經典的資料結構數量有限,但是我們常常重複著一些為了實現向量、連結串列等結構而編寫的程式碼,這些程式碼都十分相似,只是為了適應不同資料的變化而在細節上有所出入。STL容器就為我們提供了這樣的方便,它允許我們重複利用已有的實現構造自己的特定型別下的資料結構,透過設定一些模版類,STL容器對最常用的資料結構提供了支援,這些模板的引數允許我們指定容器中元素的資料型別,可以將我們許多重複而乏味的工作簡化。

容器部分主要由標頭檔案,,,,,組成。對於常用的一些容器和容器介面卡(可以看作由其它容器實現的容器),可以透過下表總結一下它們和相應標頭檔案的對應關係。

資料結構 描述 實現標頭檔案 向量(vector) 連續的元素 列表(list) 由節點組成的雙向連結串列,每個結點包含著一個元素 雙佇列(deque) 連續儲存的指向不同元素的指標所組成的陣列 集合(set) 由節點組成的紅黑樹,每個節點都包含著一個元素,節點之間以某種作用於元素對的謂詞排列,沒有兩個不同的元素能夠擁有相同的次序 多重集合(multiset) 允許存在兩個次序相等的元素的集合 棧(stack) 後進先出的值的排列 佇列(queue) 先進先出的執的排列 優先佇列(priority_queue) 元素的次序是由作用於所儲存的值對上的某種謂詞決定的的一種佇列 對映(map) 由{鍵,值}對組成的集合,以某種作用於鍵對上的謂詞排列 多重對映(multimap) 允許鍵對有相等的次序的對映

四、迭代器

下面要說的迭代器從作用上來說是最基本的部分,可是理解起來比前兩者都要費力一些(至少筆者是這樣)。軟體設計有一個基本原則,所有的問題都可以透過引進一個間接層來簡化,這種簡化在STL中就是用迭代器來完成的。概括來說,迭代器在STL中用來將演算法和容器聯絡起來,起著一種黏和劑的作用。幾乎STL提供的所有演算法都是透過迭代器存取元素序列進行工作的,每一個容器都定義了其本身所專有的迭代器,用以存取容器中的元素。

迭代器部分主要由標頭檔案,組成。是一個很小的標頭檔案,它包括了貫穿使用在STL中的幾個模板的宣告,中提供了迭代器使用的許多方法,而對於的描述則十分的困難,它以不同尋常的方式為容器中的元素分配儲存空間,同時也為某些演算法期間產生的臨時物件提供機制,中的主要部分是模板類allocator,它負責產生所有容器中的預設分配器。

五、對初學者學習STL的一點建議

對於之前不太瞭解STL的讀者來說,上面的文字只是十分概括地描述了一下STL的框架,對您理解STL的機制乃至使用STL所起到的幫助微乎甚微,這不光是因為深入STL需要對C++的高階應用有比較全面的瞭解,更因為STL的三個部分演算法、容器和迭代器三部分是互相牽制或者說是緊密結合的。從概念上講最基礎的部分是迭代器,可是直接學習迭代器會遇到許多抽象枯燥和繁瑣的細節,然而不真正理解迭代器又是無法直接進入另兩部分的學習的(至少對剖析原始碼來說是這樣)。可以說,適應STL處理問題的方法是需要花費一定的時間的,但是以此為代價,STL取得了一種十分可貴的獨立性,它透過迭代器能在儘可能少地知道某種資料結構的情況下完成對這一結構的運算,所以下決心鑽研STL的朋友們千萬不要被一時的困難擊倒。其實STL運用的相對統一,只要適應了它,從一個STL工具到另一個工具,都不會有什麼大的變化。

對於STL的使用,也普遍存在著兩種觀點。第一種認為STL的最大作用在於充當經典的資料結構和演算法教材,因為它的涉及了許多具體實現方面的問題。第二種則認為STL的初衷乃是為了簡化設計,避免重複勞動,提高效率,因此應該是“應用至上”的,對於原始碼則不必深究。筆者則認為分析原始碼和應用並不矛盾,透過分析原始碼也能提高我們對其應用的理解,當然根據具體的目的也可以有不同的側重。

最後要說的是,STL是ANSI/ISO C++標準的一部分,所以對於一個可以有多種C++實現的過程,首先考慮的應該是STL提供的模板(高效且可移植性好),其次才是各個廠商各自相應的庫(高效但可移植性不好)以及自己去編寫程式碼(可移植性好但低效)。


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