C++ 順序容器入門

定義一個順序容器

爲了定義一個容器對象 ,我們必須先包含相關聯的頭文件, 應該是下列頭文件之一

#include <vector>
#include <list>
#include <deque>
#include <map>
#include <set>

容器對象的定義以容器類型的名字開始 ,後面是所包含的元素的實際類型,例如

vector< string > svec;
list< int > ilist;

定義了 svec 是一個內含 string 對象的主 vector, 以及 ilist 是一個 int 型對象的空 list。 svec和 ilist 都是空的。爲了確認這一點, 我們可以調用 empty()操作符 ,例如:

if ( svec.empty() != true )
; // 喔, 有錯誤了

插入元素最簡單的方法是 push_back() ,它將元素插入在容器的尾部 。例如:

string text_word;
while ( cin >> text_word )
	svec.push_back( text_word );

每次從標準輸入讀取一個字符串放到 text_word 中, 然後 push_back()再將 text_word 字符串的拷貝插入到 svec 中。 list 和 deque 容器也支持 push_front(), 它把新元素插入在鏈表的前端, 例如 :假設我們有一個 int 型的內置數組如下:

int ia[ 4 ] = { 0, 1, 2, 3 };

用 push_back():

for ( int ix = 0; ix < 4; ++ix )
	ilist.push_back( ia[ ix ] );

創建序列 0 1 2 3 然而 如果使用 push_front():

for ( int ix = 0; ix < 4; ++ix )
	ilist.push_front( ia[ ix ] );

則在 ilist 中創建序列 3 2 1 0
另外 ,我們或許希望爲容器指定一個顯式的長度, 長度可以是常量, 也可以是非常量表達式:

#include <list>
#include <vector>
#include <string>
extern int get_word_count( string file_name );
const int list_size = 64;
list< int > ilist( list_size );
vector< string > svec(get_word_count(string("Chimera")));

注:
如果一個 C++編譯器不支持缺省模板參數, 那麼它要求第二個實參指定分配器 (allocator)。 在這樣的編譯器實現下 ,上述兩個定義被聲明如下

list< int > ilist( list_size, - 1 );
vector< string > svec( 24, "pooh" );

allocator 類封裝了分配和刪除動態內存的抽象過程, 它也是標準庫預定義的類. 實際上它使用了 new 和 delete操作符 ,使用這樣的分配器類有兩個目的 :通過把容器與內存分配策略的細節分開, 這可以簡化容器類的實現 ;其次, 程序員有可能實現或者指定其他的內存分配策略, 比如使用共享內存.
如果容器的主要行爲是在前端插入元素 則 deque 比 vector 的效率高 所以我們應該優先選擇 deque

容器中的每個元素都被初始化爲與該類型相關聯的缺省值 。對於整數 :將用缺省值0 初值化所有元素。 對於 string 類 :每個元素都將用 string 的缺省構造函數初始化。

除了用相關聯的初始值來初始化每個元素外 ,我們還可以指定一個值 ,並用它來初始化每個元素。
例如:

list< int > ilist( list_size, - 1 );
vector< string > svec( 24, "pooh" );

除了給出初始長度外 ,我們還可以通過 resize()操作重新設置容器的長度。 例如 ,當我們
寫下面的代碼時:

svec.resize( 2 * svec.size() );

我們將 svec 的長度加了一倍 ,每個新元素都被初始化爲 與元素底層類型相關聯的缺
省值 。
如果我們希望把每個新元素初始化爲某個其他值, 則可以把該值指定爲第二個參
數:

// 將新元素初始化爲 piglet
svec.resize( 2 * svec.size(), "piglet" );

那麼 svec 的原始定義的容量是多少 ?它的初始長度是 24 個元素 。
它的初始容量可能是多少? 對——svec 的容量也是 24 。

一般地, vector 的最小容量是它的當前長度, 當 vector的長度加倍時 ,容量一般也加倍。
我們也可以用一個現有的容器對象 初始化一個新的容器對象 。例如:

vector< string > svec2( svec );
list< int > ilist2( ilist );

每個容器支持一組關係操作符 ,我們可以用來比較兩個容器 。這些關係操作符分別是:
等於 、不等於 、小於 、大於、 小於等於、大於等於
容器的比較是指兩個容器的元素之間成對進行比較 。如果所有元素相等而且兩個容器含有相同數目的元素 ,則兩個容器相等,否則 ,它們不相等。 第一個不相等元素的比較決定了兩個容器的小於或大於關係 。
例如 ,下面是一個程序的輸出 ,它比較了五個 vector:

ivec1: 1 3 5 7 9 12
ivec2: 0 1 1 2 3 5 8 13
ivec3: 1 3 9
ivec4: 1 3 5 7
ivec5: 2 4
// 第一個不相等元素: 1, 0
// ivec1 大於 ivec2
ivec1 < ivec2 // flase
ivec2 < ivec1 // true
// 第一個不相等元素: 5, 9
ivec1 < ivec3 // true
// 所有元素相等, 但是, ivec4 的元素少
// 所以 ivec4 小於 ivec1
ivec1 < ivec4 // false
// 第一個不相等元素: 1, 2
ivec1 < ivec5 // true
ivec1 == ivec1 // true
ivec1 == ivec4 // false
ivec1 != ivec4 // true
ivec1 > ivec2 // true
ivec3 > ivec1 // true
ivec5 > ivec2 // true

我們能夠定義的容器的類型有三個限制 。實際上, 它們只適用於用戶定義的類類型

  • 元素類型必須支持等於操作符
  • 元素類型必須支持小於操作符 ,前面討論的所有關係操作符都用這兩個操作符來實現
  • 元素類型必須支持一個缺省值 ,對於類類型 ,即指缺省構造函數
    所有預定義數據類型 ,包括指針 ,都滿足這些限制。 C++標準庫給出的所有類類型也一樣
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章