最近這段時間一直都在自學C++,所以這裡總結下自己這段時間的學習過程,通過這種方式來鞏固自己學到的內容和以備後面復習所用,另外,希望這系列文章可以幫助到其他自學C++的朋友們。
由於本人之前主要研究C#語言,在自學C++的過程中,經常會把C++中內容與C#中內容進行對比來理解,所以這系列文章的內容也會與C#進行比較,從而來說明語言都是想通的,只要你掌握好一門語言,學習其他語言都可以舉一反三。
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中容器可分為序列式容器和關聯式容器,其中,序列式容器的每個元素的位置取決於元素被插入時設置的位置,和元素值本身無關,而,關聯式容器的元素位置取決於特定的排序規則,和插入順序無關。意思就說,序列式容器中每個元素的位置與插入的順序對應,而關聯式容器中元素會根據特定的排序規則對每個元素進行排序,與元素插入的順序無關,更多內容可以參考本系列後面文章介紹。
序列式容器包括:vector、list和deque,而關聯式容器有:set、multiset、map和multimap。下表列出了每個容器的簡單介紹:STL實現要點是將容器和算法分開,使兩者彼此獨立。迭代器使兩個聯系起來,迭代器提供訪問容器中的方法。迭代器實質上是一種智能指針,它重載了->和*操作符。事實上,C++指針也是一種迭代器。在C#中同樣有迭代器的概念,具體參考MSDN:http://msdn.microsoft.com/zh-cn/library/dscyy5s0(v=vs.90).aspx,不同的是,在C++ 中迭代器分為五類,這五類分別為:
函數對象,又稱為仿函數,STL中的函數對象就是重載了運算符()的模板類的對象,因為該類對象的調用方式類似與函數的調用方式,所以稱為函數對象,函數對象類似於C#中的委托對象,熟悉C#的朋友肯定知道,我們可以隱式地調用委托,即委托對象(實參),更多關於委托內容可以參考我的博文:委托的本質論。
適配器是用來修改其他組件接口,與設計模式中的適配器模的達到的效果是一樣的。STL中定義了3種形式的適配器:容器適配器、迭代器適配和函數適配器。
容器適配器——包括棧(stack)、隊列(queue)和優先隊列(priority_queue),容器適配器是對基本容器類型進行進一步的封裝,從而轉換為新的接口類型。
迭代器適配器——對STL中基本迭代器的功能進行擴展,該類適配器包括反向迭代器、插入迭代器和流迭代器。
函數適配器——通過轉換或修改來擴展其他函數對象的功能。該類適配器有否定器、綁定器和函數指針適配器。函數對象適配器的作用就是使函數轉化為函數對象,或將多參數的函數對象轉換為少參數的函數對象,如STL中bind2nd()就是綁定器。
當容器中保存的是用戶自定義類型數據時,有的數據類型結構簡單,占用的空間很小,而有的數據類型結構復雜,占用的內存空間較大;並且有的應用程序需要頻繁地進行數據的插入刪除操作,這樣就需要對內存空間進行頻繁地申請和釋放工作,然而對內存的頻繁操作,會產生嚴重的性能問題,為了解決這個問題,STL中提供了兩個空間配置器,一個是簡單空間配置器,僅僅對C運行庫中malloc和free進行了簡單的封裝操作,另一個是“基於內存池的控件配置器”,即容器在每次申請內存的時候,內存池會基於一定的策略,向操作系統申請交大的內存空間,從而避免每次都向OS申請內存。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<< <<
上面代碼的輸出結果如下圖所示: