程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 跟我學STL系列(1)——STL入門介紹

跟我學STL系列(1)——STL入門介紹

編輯:C++入門知識

一、引言

最近這段時間一直都在自學C++,所以這裡總結下自己這段時間的學習過程,通過這種方式來鞏固自己學到的內容和以備後面復習所用,另外,希望這系列文章可以幫助到其他自學C++的朋友們。

由於本人之前主要研究C#語言,在自學C++的過程中,經常會把C++中內容與C#中內容進行對比來理解,所以這系列文章的內容也會與C#進行比較,從而來說明語言都是想通的,只要你掌握好一門語言,學習其他語言都可以舉一反三。

二、STL是什麼

STL全稱為Standard Template Library,即標准模板庫,該庫提供一些常用的容器對象和一些通用的算法等,大家可以理解STL就是一個庫,該庫幫我們封裝了很多容器類和通用的方法,我們可以通過調用該庫中封裝好的方法和容器類來進行編程,相比C#而言,STL就好比.NET類庫中的某個DLL,例如,C# 中,List<T>類存在於mscorlib.dll中System.Collections.Generic命名空間下,C++ 中,list<T>存在於list頭文件中std命名空間下,所以C++代碼中要使用list<T>容器(在C++中把list成為容器,即一系列元素的集合),必須先通過#include <list>引入list頭文件,類似與C#中的添加mscorlib.dll引言,再使用use namespace std引入命名空間,類似與C#中using System.Collections.Generic代碼。

三、STL 六大組件

STL通過模板抽象了基於數據結構之上的普遍行為,形成了獨特的STL算法。在STL中,這些數據結構成為容器。在容器和算法之間通過中間體:迭代器來進行連接,迭代器可以看做是數據結構和算法之間的紐帶,它降低了數據結構和算法之間的耦合度。STL中國又包括六大核心組件,它們分別是:

 

  • 容器(Container)
  • 算法(Algorithm)
  • 迭代器(Iterator)
  • 函數對象,又稱仿函數(Function object)
  • 適配器(Adaptor)
  • 空間配置器(Allocator)
下面對這六大組件分別進行介紹。

3.1 容器

STL中容器可分為序列式容器和關聯式容器,其中,序列式容器的每個元素的位置取決於元素被插入時設置的位置,和元素值本身無關,而,關聯式容器的元素位置取決於特定的排序規則,和插入順序無關。意思就說,序列式容器中每個元素的位置與插入的順序對應,而關聯式容器中元素會根據特定的排序規則對每個元素進行排序,與元素插入的順序無關,更多內容可以參考本系列後面文章介紹。

序列式容器包括:vector、list和deque,而關聯式容器有:set、multiset、map和multimap。下表列出了每個容器的簡單介紹:


上面列出的所有容器在C#中都有相應的對應形式,它們之間的對應關系為: std::vector——List<T>類 std::list——LinkedList<T>類 std::map——SortedDictionary<TKey,TValue>類 std::set——HashSet<T>類,但這裡需要明確,STL中的set是以紅黑樹作為底層數據結構,而C#中HashSet<T>類是以哈希表作為底層數據結構,因為其兩者使用數據結構的不同,從而導致查詢效率不同,set查找的花費時間為O(logn),這也是紅黑樹查詢時間,而HashSet的查詢花費時間為O(1)。 std::multimap——Dictionary<TKey,List<TValue>>,該類在C#中也不存在的,也需要自己實現 std::multiset——Dictionary<TKey,int>(第二個參數存儲著Key的數量) C++中的std::deque在C#中並沒有找到相對應地實現,不過我們可以自己實現,具體實現可以參考文章:A Deque Class in C#。 在上面的對應關系中,C#中的SortedDictionary<TKey,TValue>類是以二叉查找樹作為底層數據結構的,而Dictionary<TKey,TValue>類是以哈希表作為底層數據結構的。因為其數據結構的不同從而導致操作效率的不同,下表列出了兩者各種操作的區別。

3.2 算法

算法是用來操作容器中數據的模板函數,它抽象了對數據結構的操作行為。要使用STL中定義的算法,應首先引入<algorithm>頭文件。例如STL中的sort()函數可以對容器中的數據進行排序,可以使用find()函數來搜索容器中的某個元素。這裡的算法可以與C#中泛型方法進行對比來理解。

3.3 迭代器

STL實現要點是將容器和算法分開,使兩者彼此獨立。迭代器使兩個聯系起來,迭代器提供訪問容器中的方法。迭代器實質上是一種智能指針,它重載了->和*操作符。事實上,C++指針也是一種迭代器。在C#中同樣有迭代器的概念,具體參考MSDN:http://msdn.microsoft.com/zh-cn/library/dscyy5s0(v=vs.90).aspx,不同的是,在C++ 中迭代器分為五類,這五類分別為:

3.4 函數對象

函數對象,又稱為仿函數,STL中的函數對象就是重載了運算符()的模板類的對象,因為該類對象的調用方式類似與函數的調用方式,所以稱為函數對象,函數對象類似於C#中的委托對象,熟悉C#的朋友肯定知道,我們可以隱式地調用委托,即委托對象(實參),更多關於委托內容可以參考我的博文:委托的本質論。

3.5 適配器

適配器是用來修改其他組件接口,與設計模式中的適配器模的達到的效果是一樣的。STL中定義了3種形式的適配器:容器適配器、迭代器適配和函數適配器。

容器適配器——包括棧(stack)、隊列(queue)和優先隊列(priority_queue),容器適配器是對基本容器類型進行進一步的封裝,從而轉換為新的接口類型。

迭代器適配器——對STL中基本迭代器的功能進行擴展,該類適配器包括反向迭代器、插入迭代器和流迭代器。

函數適配器——通過轉換或修改來擴展其他函數對象的功能。該類適配器有否定器、綁定器和函數指針適配器。函數對象適配器的作用就是使函數轉化為函數對象,或將多參數的函數對象轉換為少參數的函數對象,如STL中bind2nd()就是綁定器。

當容器中保存的是用戶自定義類型數據時,有的數據類型結構簡單,占用的空間很小,而有的數據類型結構復雜,占用的內存空間較大;並且有的應用程序需要頻繁地進行數據的插入刪除操作,這樣就需要對內存空間進行頻繁地申請和釋放工作,然而對內存的頻繁操作,會產生嚴重的性能問題,為了解決這個問題,STL中提供了兩個空間配置器,一個是簡單空間配置器,僅僅對C運行庫中malloc和free進行了簡單的封裝操作,另一個是“基於內存池的控件配置器”,即容器在每次申請內存的時候,內存池會基於一定的策略,向操作系統申請交大的內存空間,從而避免每次都向OS申請內存。STL中的空間配置器就是負責內存的分配和釋放的工作。

四、STL中容器使用示例

看完STL組件之後,現在我們具體看看如何使用STL中的容器進行編程,下面示例是對vector容器進行簡單的幾個操作。具體代碼如下:

#include <iostream>  

#include <vector>  

#include <algorithm>  

 
    vector<>( i=;i<;i++

     a[]={,,,,,<> vec2(a,a+); 
    vector<>
    (begin =vec.begin();begin!=vec.end();begin++
        cout<<*begin<<  <<

    cout<<<<(begin =vec2.begin();begin!=vec2.end();begin++
        cout<<*begin<<  <<

上面代碼的輸出結果如下圖所示:

五、小結

該篇博文只是對STL進行一個全面的介紹,希望初學者對STL能有一個全面的認識,並且本文對於一些難懂的內容,都用C#中相關的內容進行了解釋,如果有像我一樣,之前學習C#朋友可以對比來進行理解,關於STL六大組件的詳細介紹會在後面文章進行介紹。    

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved