C++---CHAPTER 9: CONTAINER

  • 順序容器
vector 尾部之外的位置插入或刪除元素可能很慢
deque 頭尾位置插入、刪除速度很快
list 任何位置插入、刪除速度很快
forward_list 只支持單向順序訪問,任何位置插入、刪除都很快。
array 固定大小數(shù)組。不能添加刪除元素
string 隨機(jī)訪問快、尾部插入刪除很快。
  • 容器操作
類型別名
iterator 此容器類型的迭代器類型
const_iterator 讀取元素,不能修改元素的迭代器類型
size_type 無符號(hào)類型,保存此容器類型的最大可能容器的大小
difference_type 帶符號(hào)整數(shù)類型,兩個(gè)迭代器之間的距離
value_type 元素類型
reference 元素的左值類型;與value_type&含義相同
const_reference 元素的const左值類型(vonst vlue_type&)
構(gòu)造函數(shù)
C c; 默認(rèn)構(gòu)造函數(shù),構(gòu)造空容器
C c1(c2); 構(gòu)造c2的拷貝到c1
C c(b,e); 構(gòu)造c,將接待器b和e范圍的元素拷貝到c(不支持array)
C c{a, b, c,...} 列表初始化c
賦值與swap
C1 = c2
C1 = {a, b, c,...}
a.swap(b);swap(a,b) 交換a與b的元素
大小
c.size() c中元素的數(shù)目(不支持forward_list)
c.max_size() c可保存的最大元素?cái)?shù)目
c.empty()
添加或刪除元素 在不同容器中,操作的接口不同
c.insert(args) 將args中的元素拷貝到c
c.emplace(inits) 使用inits構(gòu)造c中的一個(gè)元素
c.erase(args) 刪除args指定的元素
c.clear() 刪除c中的所有元素,返回void
關(guān)系運(yùn)算符 所有容器都支持:如==、!=
獲取迭代器
c.cbegin(),c.cend() 返回const_iterator
reverse_iterator 逆序?qū)ぶ返牡?/td>

容器定義和初始化

C seq(n);       // seq包含n個(gè)元素,都被值初始化
C seq(n, t);  // seq包含n個(gè)值為t的元素
list<string> authors = {"Milton", "Austen"}; //列表初始化
  • notes: 1. 將一個(gè)容器初始化為另一個(gè)容器的拷貝時(shí),兩個(gè)容器的容器類型和元素類型都必須相同。
  1. 順序容器的構(gòu)造函數(shù)才接受大小參數(shù),關(guān)聯(lián)容器并不支持。
  • 標(biāo)準(zhǔn)庫 array
    使用array必須指定元素類型和大?。?/li>
array<int, 42> // 類型為:保存42個(gè)int的數(shù)組
 array<int>:: size_type j;  //錯(cuò)誤

不能對(duì)內(nèi)置數(shù)組類型進(jìn)行拷貝,但是array類型是可以的:

array<int ,10> digits = {0,1,2,3,4,5,6,7,8,9};
array<int, 10> copy = digits; // right

容器賦值運(yùn)算

賦值和swap

array<int, 10> a1 = {...};
array<int 10> a2 = {0}; //所有元素均為 0
a2 = {0}; //錯(cuò)誤,不能將一個(gè)花括號(hào)列表賦予數(shù)組
// 通常swap比從c2向c1拷貝元素要快
swap(c1,c2);
c1.swap(c2);  

seq.assign(b, e); // 將seq中的元素替換為迭代器b和e所表示的范圍的元素,迭代器b、e不能指向seq中的元素
seq.assign(il); // 將seq中的元素替換為初始化列表il中的元素
seq.assign(n,t); // 將seq中的元素替換為n個(gè)值為t的元素
  • 警告:賦值相關(guān)運(yùn)算會(huì)導(dǎo)致指向左邊容器內(nèi)部的迭代器、引用和指針失效。而swap操作將容器內(nèi)容交換不會(huì)導(dǎo)致指向容器的迭代器、引用和指針失效(array和string除外)。

  • 順序容器的assign
    允許我們從一個(gè)不同但相容的類型賦值,或者從容器的一個(gè)子序列賦值。assign操作用參數(shù)所指定的元素(的拷貝)替換左邊容器中的所有元素。

list<string> names;
vector<const char*> oldstyle;
names = oldstyle; //錯(cuò)誤,容器類型不匹配
names.assign(oldstyle.cbegin(), oldstyle.cend()); //正確 可以將const char* 轉(zhuǎn)換為string

向順序容器添加元素

c.push_back(t) , c.emplace_back(args) c的尾部創(chuàng)建一個(gè)值為t或由args創(chuàng)建的元素。
c.insert(p,t) , c.emplace(p,args) 在迭代器p指向的元素之前創(chuàng)建一個(gè)值為p或由args創(chuàng)建的元素。
c.insert(p, n , t) 在迭代器p指向的元素之前插入n個(gè)值為t的元素。返回新添加的第一個(gè)元素的迭代器,若n為0,返回p
c.insert(p, b, e) 將迭代器b、e指定的范圍內(nèi)的元素插入到迭代器p指向的元素之前。b、e不能指向c中的元素。 返回新添加的第一個(gè)元素的迭代器,若n為0,返回p
c.insert(p , il) il是一個(gè)花括號(hào)保衛(wèi)的元素值列表,將這些值插入到p指向的元素之前。 返回新添加的第一個(gè)元素的迭代器,若n為0,返回p
  • insert的返回值
    下面的例子,iter每次都指向新加入元素的位置:
list<string> lst;
auto iter = lst.begin();
while(cin>>word)
  iter = lst.insert(iter, word); //等價(jià)于調(diào)用 push_front
  • 使用emplace操作
    假設(shè)c里保存的是Sales_data成員:
c.emplace_back("970", 25, 15.99);
c.push_back("970", 25, 15.99); //錯(cuò)誤,沒有接受三個(gè)參數(shù)的push_back
c.push_back(Sales_data("970", 25, 15.99));

在調(diào)用emplace_back時(shí),會(huì)在容器管理的內(nèi)存空間中直接創(chuàng)建對(duì)象,而調(diào)用push_back則會(huì)創(chuàng)建一個(gè)局部臨時(shí)對(duì)象,并壓入容器中。

在順序容器匯總訪問元素

  • 容器中沒有元素,訪問操作是未定義的。
  • 包括array在內(nèi)每個(gè)順序容器都有一個(gè)front成員函數(shù),除去forward_list之外的所有順序容器都有back成員函數(shù)。
  vector<int> c={1,2,3,4,5,6};
  if (!c.empty()){
    // val和val2是c中第一個(gè)元素值的拷貝
    auto val = *c.begin(), val2 = c.front();
    // val3和val4是c中最后一個(gè)元素值的拷貝
    auto last =c.end();
    auto val3 =*(--last); // 不能遞減forward_list迭代器
    auto val4 = c.back();
    cout << val << " " << endl;
    cout << val2 << " " << endl;
    cout << val3 << " " << endl;
    cout << val4 << " " << endl;
  }
  • 訪問成員函數(shù)返回的是引用:front、back、at、下標(biāo)都是返回引用,如果容器是一個(gè)const對(duì)象,返回值是const的引用。
  vector<int> c={1,2,3,4,5,6};
  if (!c.empty()){
    c.front() = 42;
    auto &v = c.back(); // v是c.back()的一個(gè)引用
    v = 1024;
    cout << c.back() << endl;
    auto v2 = c.back(); // v2不是一個(gè)引用,它是c.back()的一個(gè)拷貝
    v2 = 0;
    cout <<c.back();
  }


1024
1024
  • 下標(biāo)操作和安全的隨機(jī)訪問:at在下標(biāo)越界的情況下,會(huì)拋出一個(gè)out_of_range的異常。
vector<string> svec;
cout << svec[0]; // 運(yùn)行時(shí)錯(cuò)誤
cout << svec.at(0); //拋出一個(gè)異常

順序容器的刪除操作

  • 注意:刪除deque中除首尾位置之外的任何元素都會(huì)是所有迭代器、引用、指針失效。指向vector、string中刪除點(diǎn)之后的迭代器、引用、指針失效。
c.pop_back() 刪除c中的尾元素。c為空,函數(shù)行為未定義。函數(shù)返回void
c.pop_front() 刪除c中的首元素。c為空,函數(shù)行為未定義。函數(shù)返回void
c.erase(p) 刪除迭代器p指定的元素,返回一個(gè)指向被刪除元素之后元素的迭代器,若p是尾后迭代器,則函數(shù)行為未定義
c.erase(b, e) 將迭代器b、e指定的范圍內(nèi)的元素刪除。若e是尾后迭代器,則函數(shù)返回尾后迭代器
c.clear() 刪除所有元素,返回void

改變?nèi)萜鞯拇笮?/h4>

resize增大或縮小容器,array不支持。如果當(dāng)前大小大于所要求的大小,容器后部的元素被刪除;如果當(dāng)前大小小于新大小,新元素會(huì)添加:

list<int> ilist(10, 42); // 10個(gè)int:每個(gè)值為42
ilist.resize(15); // 將5個(gè)值為0的元素添加到ilist尾部
ilist.resize(25, -1); //  將10個(gè)值為-1的元素添加到ilist末尾
ilist.resize(5); // 從ilist末尾刪除20個(gè)元素

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • #1.順序容器概述 #2.容器庫概覽迭代器容器類型成員begin和end成員容器定義和初始化賦值和swap容器大小...
    MrDecoder閱讀 1,279評(píng)論 0 1
  • 參考書籍:C++ primer 第四版 順序容器:它將單一類型元素聚集起來成為容器,然后根據(jù)位置來存儲(chǔ)和訪問這些元...
    Mr希靈閱讀 1,204評(píng)論 0 7
  • 專業(yè)考題類型管理運(yùn)行工作負(fù)責(zé)人一般作業(yè)考題內(nèi)容選項(xiàng)A選項(xiàng)B選項(xiàng)C選項(xiàng)D選項(xiàng)E選項(xiàng)F正確答案 變電單選GYSZ本規(guī)程...
    小白兔去釣魚閱讀 10,577評(píng)論 0 13
  • 什么是容器 首先,我們必須理解一下什么是容器,在C++ 中容器被定義為:在數(shù)據(jù)存儲(chǔ)上,有一種對(duì)象類型,它可以持有其...
    Jack_Cui閱讀 523評(píng)論 0 2
  • C++ 標(biāo)準(zhǔn)模板庫(STL) 作者:AceTan,轉(zhuǎn)載請(qǐng)標(biāo)明出處! 0x00 何為STL## STL(Standa...
    AceTan閱讀 5,141評(píng)論 3 44

友情鏈接更多精彩內(nèi)容