1.順序容器:vector,deque,list
容器類共享公共接口,只要學會其中一種類型就能運用另一種類型。每種容器提供一組不同的時間和功能這種方案,通常不需要修改代碼,秩序改變類型聲明,每一種容器類型替代另一種容器類型,就可以優化程序的性能。容器值定義了少量操作,大多數額外的操作有算法庫提供。
2.為了使用順序容器,要包含頭文件:
1 #include<vector> 2 #include<list> 3 #include<deque>
3.所有容器都是類模板,要定義某種容器要,要在容器明後加一對尖括號,尖括號裡放元素類型:
1 vector<string> vec; 2 list<int> lis; 3 deque<string>;
所有容器類型都定義了默認的構造函數,用於創建制定類型的空容器對象。默認的構造函數都不帶參數。
注:當元素類型為容器類型時,尖括號和元素類型之間要加空格
1 vector< vector<int> > vec;
4.容器的初始化
初始化
解釋
試用范圍
C<T> c
創建一個名為c的空容器
所有容器
C<T> c(c2)
創建容器c2的副本c;c2和c必須具有相同的容器類型,並存放相同類型的元素
所有容器
C<T> c(b,e)
創建c,其元素是迭代器b和e標示范圍內的元素的副本,b和e可以是具有相同元素類型的其他容器類型
所有容器
C<T> c(n,t)
用於創建n個值為t的容器c,t必須為T類型或可轉換為該類型的值
順序容器
C<T> c(n)
創建有n個初始化元素的容器c
順序容器
1 vector<int> vec(10,1); 2 vector<int> vec1(vec); //OK 3 list<int> l(vec); //error,此種初始化方式要求容器類型和元素類型都相同 4 list<int> l(vec.begin(),vec.end()); //ok,可以通過迭代器間接實現具有相同元素類型的不同容器間的賦值
5.元素類型的約束
最低要求:
引用不能做元素類型,因為引用不支持一般意義的賦值運算
標准輸入輸出(I/O)不能做元素類型,因為不支持復制或賦值運算,但其他標准庫類型可以
一些容器操作對元素類型還有特殊要求,我們可以定義該類型的容器,但不能使用這些對元素類型有要求的操作。假設類Foo沒有默認的構造函數,但提供了一個int型形參的構造函數,現有以下聲明:
1 vector<Foo> vec; //ok,不需要初始化元素 2 vector<Foo> vec(10); //error,創建有10個初始化元素的容器vec,但Foo沒有默認的構造函數 3 vector<Foo> vec(10,1); //ok,Foo提供了int型形參的構造函數。
注:當創建的容器包含元素的初始化時,該元素類型必須能夠提供相應的構造函數。
6.迭代器
同容器類型一樣,所有迭代器具有相同的接口,當一種迭代器支持某種操作時,那麼支持這種操作的其他迭代器會以相同的方式支持這種操作
常用的迭代器操作:
操作
解釋
適用范圍
*it
返回迭代器所指向的元素的引用
所有容器
it->mem
對it進行解引用,獲取mem,等效(*it).mem
所有容器
++it , it++
it加1,指向容器下一元素
所有容器
--it , it--
it減1,指向容器前一元素
所有容器
it1==it2
比較兩個迭代器是否相等,當兩個迭代器指向同一容器裡的同一元素,或超出末端的下一位置時,兩個迭代器相等
所有容器
it1!=it2
>,<,
<=,>=
當一個迭代器指向的元素在容器中的位置位於另一個迭代器指向的元素指向,則前一個迭代器小於後一個迭代器
vector,deque
vector和deque容器的迭代器支持迭代器算數運算,以及所有的關系運算;因為只有這兩種容器支持元素的快速、隨機訪問,因而可以有效的實現算數和關系運算。
注:list的迭代器不支持算數運算和除==,!=之外的關系運算
7.容器定義的類型別名
size_type
無符號整形
iterator
此容器類型的迭代器
const_itreator
元素的只讀迭代器
reverse_iterator
按逆序尋址元素的迭代器
congst_reverse_iterator
元素的只讀逆序迭代器
difference_type
存儲兩個迭代器差值的有符號整型
value_type
元素類型
reference
元素的左值類型,是value_type&的同意
const_reference
同const value_type
8.容器的成員函數
成員函數
含義
返回值
c.begin()
指向容器第一個元素
迭代器
c.end()
指向容器最後一個元素的下一位置
迭代器
c.rbegin()
指向容器最後一個元素
逆序迭代器
c.rend()
指向第一個元素前面的位置
逆序迭代器
c.push_back(t)
在容器尾部插入元素t
void
c.push_front(t)
在容器前端插入元素t;只適用於
list,deque
void
c.insert(p,t)
在迭代器p所指向的元素前面插入值為t的新元素
指向新元素的迭代器
c.insert(p,n,t)
在迭代器p所指向的元素前面插入n個值為t的新元素
void
c.insert(p,b,e)
在迭代器p所指向的元素前面插入由迭代器b和e標記的范圍內的元素
void
c.size()
返回容器的實際元素個數
容器元素個數
c.max_size()
返回容器c可容納的最多元素個數
最多元素個數
c.capacity()
返回容器的大小,>=c.size();獲取在容器需要分配更多的存儲空間之前可以存儲的元素總數
c.reserve()
容器預留的空間,在預留的空間用完之前,不會重新分配新的空間。
c.empty()
判讀容器是否為空
bool值
c.resize(n)
調整容器長度,當n<c.size(),則刪除多余的元素,否則,添加采用值初始化的新元素
void
c.resize(n,t)
調整容器c的大小,當n>c.size()時,新添加的元素值為t
void
c.back()
返回最後一個元素的引用,若容器為空,則該操作未定義
最後一個元素的引用
c.front()
返回第一個元素的引用,若容器為空,則該操作未定義
第一個元素的引用
c[n]
返回下標為n的元素的引用,只適用於deque,vector
越界,運行出錯
下標為n的元素的引用
c.at[n]
返回下標為n的元素的引用,只適用於deque,vector
越界,運行出錯,並拋出異常
下標為n的元素的引用
c.erase(p)
刪除迭代器p所指向的元素,返回一個迭代器,指向被刪除元素後面的元素,如指向最後一個元素,則返回的迭代器指向超出容器末端的下一位置。若p本身指向超出容器末端的下一位置,則該操作未定義
返回一個迭代器
c.erase(b,e)
刪除迭代器b和e所標記的范圍內所有的元素,不包括e指向的元素
返回一個迭代器(迭代器要求同上)
c.clear()
刪除c內的所有元素
void
c.pop_back()
刪除c的最後一個元素
void
c.pop_front()
刪除c的第一個元素,只適用於list和deque容器
void
find(b,e,val)
查找迭代器b和e范圍內的元素val,返回指向找到的第一個元素的迭代器,若沒有找到,則返回指向容器末端下一位置的迭代器;使用find必須包括
#include<algorithm>
指向第一個元素的迭代器
count(b,e,val)
在迭代器b和e范圍內查找值為val的元素個數,使用count必須包括#include<algorithm>
返回元素個數
c1=c2
刪除容器c1中的所有元素,然後將c2的元素復制到c1.c1和c2類型必須相同
c1.swap()
交換迭代器存放的元素,迭代器不會失效
void
c.assign(b,e)
重置c的元素,將迭代器b和e標記范圍內的元素復制到c中。b和e不能是指向c中元素的迭代器,因為在重置時會先刪除c中的內容
void
c.assign(n,t)
將c容器的內容重置為n個t
void
注:capacity和reseve區別,capacity在插入新元素的過程中,即使還有剩余空間可能會增加,但當用reseve設定預留空間後,在該空間沒有滿之前,capacity不會繼續增加,通常reseve和capacity同時使用,避免使用容器過程中多次分配空間帶來的消耗;
9.迭代器失效
insert
在vector,deque中插入元素,指向新插入元素後面的迭代器失效
resize
若resize壓縮了容器,則已刪除的元素迭代器失效
賦值操作c1=c2
做操作數的所有迭代器失效
assign
所有迭代器失效
注:swap不會是迭代器失效
10.容器的選用
vecetor和deque支持隨機訪問,但在erase和insert元素時會移動元素
list不支持隨機訪問,但插入刪除元素時不用移動元素