迭代器的使用
目錄
1.迭代器的使用
?????? 為了提高C++編程的效率,STL中提供了許多容器,包括vector、list、map、set等。有些容器例如vector可以通過腳標(biāo)索引的方式訪問容器里面的數(shù)據(jù),但是大部分的容器不能使用這種方式,例如list、map、set。STL中每種容器在實(shí)現(xiàn)的時(shí)候設(shè)計(jì)了一個(gè)內(nèi)嵌的iterator類,不同的容器有自己專屬的迭代器,使用迭代器來訪問容器中的數(shù)據(jù)。除此之外,通過迭代器,可以將容器和通用算法結(jié)合在一起,只要給予算法不同的迭代器,就可以對不同容器執(zhí)行相同的操作,例如find查找函數(shù)。迭代器對指針的一些基本操作如*、->、++、==、!=、=進(jìn)行了重載,使其具有了遍歷復(fù)雜數(shù)據(jù)結(jié)構(gòu)的能力,其遍歷機(jī)制取決于所遍歷的數(shù)據(jù)結(jié)構(gòu),所有迭代的使用和指針的使用非常相似。通過begin,end函數(shù)獲取容器的頭部和尾部迭代器,end 迭代器不包含在容器之內(nèi),當(dāng)begin和end返回的迭代器相同時(shí)表示容器為空。
template<typename InputIterator, typename T> InputIterator find(InputIterator first, InputIterator last, const T &value) {while (first != last && *frist != value)++first;return first; } #include <iostream> #include <vector> #include <list> #include <algorithm> using namespace std;int main(int argc, const char *argv[]) {int arr[5] = { 1, 2, 3, 4, 5};vector<int> iVec(arr, arr + 5);//定義容器vectorlist<int> iList(arr, arr + 5);//定義容器list//在容器iVec的頭部和尾部之間尋找整形數(shù)3vector<int>::iterator iter1 = find(iVec.begin(), iVec.end(), 3);if (iter1 == iVec.end())cout<<"3 not found"<<endl;elsecout<<"3 found"<<endl;//在容器iList的頭部和尾部之間尋找整形數(shù)4list<int>::iterator iter2 = find(iList.begin(), iList.end(), 4);if (iter2 == iList.end())cout<<"4 not found"<<endl;elsecout<<"4 found"<<endl;return 0; }2.迭代器的種類
根據(jù)迭代器所支持的操作,可以把迭代器分為5類。
1)?? 輸入迭代器:是只讀迭代器,在每個(gè)被遍歷的位置上只能讀取一次。例如上面find函數(shù)參數(shù)就是輸入迭代器。
2)?? 輸出迭代器:是只寫迭代器,在每個(gè)被遍歷的位置上只能被寫一次。
3)?? 前向迭代器:兼具輸入和輸出迭代器的能力,但是它可以對同一個(gè)位置重復(fù)進(jìn)行讀和寫。但它不支持operator--,所以只能向前移動。
4)?? 雙向迭代器:很像前向迭代器,只是它向后移動和向前移動同樣容易。
5)?? 隨機(jī)訪問迭代器:有雙向迭代器的所有功能。而且,它還提供了“迭代器算術(shù)”,即在一步內(nèi)可以向前或向后跳躍任意位置,??包含指針的所有操作,可進(jìn)行隨機(jī)訪問,隨意移動指定的步數(shù)。支持前面四種Iterator的所有操作,并另外支持it + n、it - n、it += n、 it -= n、it1 - it2和it[n]等操作。
STL每種容器類型都定義了 const_iterator,只能讀取容器的值,不能修改所指向容器范圍內(nèi)元素的值。vector、string、Deque隨機(jī)存取迭代器;List、Set、map、mutiset、multimap雙向迭代器。
3.迭代器失效
容器的插入insert和erase操作可能導(dǎo)致迭代器失效,對于erase操作不要使用操作之前的迭代器,因?yàn)閑rase的那個(gè)迭代器一定失效了,正確的做法是返回刪除操作時(shí)候的那個(gè)迭代器。
#include <vector> using namespace std;int main(int argc, const char *argv[]) {int arr[5] = { 1, 2, 3, 4, 5 };vector<int> iVec(arr, arr + 5); //定義容器vector//迭代器失效 // for (vector<int>::iterator it = iVec.begin(); it != iVec.end();) { // iVec.erase(it); // }//返回erase操作之后的迭代器for (vector<int>::iterator it = iVec.begin();it != iVec.end();) {it = iVec.erase(it);}return 0; }4.迭代器的實(shí)現(xiàn)
STL中每個(gè)容器都有自己的迭代器,各種迭代器的接口相同,內(nèi)部實(shí)現(xiàn)卻不相同,這也直接體現(xiàn)了泛型編程的概念,下面在單鏈表類中內(nèi)嵌入一個(gè)iterator的類來實(shí)現(xiàn)單鏈表的迭代
1 #include <iostream>2 3 template<typename T>4 struct ListNode {5 T value;6 ListNode* next;7 ListNode() {8 next = 0;9 }10 ListNode(T val, ListNode *p = nullptr) :11 value(val), next(p) {12 }13 };14 15 template<typename T>16 class List {17 private:18 ListNode<T> *m_pHead;19 ListNode<T> *m_pTail;20 int m_nSize;21 public:22 List() {23 m_pHead = nullptr;24 m_pTail = nullptr;25 m_nSize = 0;26 }27 //從鏈表尾部插入元素28 void push_back(T value) {29 if (m_pHead == nullptr) {30 m_pHead = new ListNode<T>(value);31 m_pTail = m_pHead;32 } else {33 m_pTail->next = new ListNode<T>(value);34 m_pTail = m_pTail->next;35 }36 37 }38 39 //打印鏈表元素40 void print(std::ostream &os = std::cout) const {41 for (ListNode<T> *ptr = m_pHead; ptr != m_pTail->next ; ptr = ptr->next)42 std::cout << ptr->value << " ";43 os << std::endl;44 }45 46 //內(nèi)置迭代器47 class iterator {48 private:49 ListNode<T> *m_ptr;50 public:51 iterator(ListNode<T>* p = nullptr) :52 m_ptr(p) {53 }54 55 T operator*() const {56 return m_ptr->value;57 }58 ListNode<T>* operator->() const {59 return m_ptr;60 }61 iterator& operator++() {62 m_ptr = m_ptr->next;63 return *this;64 }65 iterator operator++(int) {66 ListNode<T>* tmp = m_ptr;67 m_ptr = m_ptr->next;68 return iterator(tmp);69 }70 71 bool operator==(const iterator &arg) const {72 return arg.m_ptr == this->m_ptr;73 }74 75 bool operator!=(const iterator &arg) const {76 return arg.m_ptr != this->m_ptr;77 }78 79 };80 81 //返回鏈表頭部指針82 iterator begin() const {83 return iterator(m_pHead);84 }85 86 //返回鏈表尾部指針87 iterator end() const {88 return iterator(m_pTail->next);89 }90 91 //其它成員函數(shù)92 93 };94 95 int main() {96 List<int> l;97 l.push_back(1);98 l.push_back(2);99 l.print(); 100 for (List<int>::iterator it = l.begin(); it != l.end(); ++it) { 101 std::cout << *it << " "; 102 } 103 std::cout << std::endl; 104 return 0; 105 }總結(jié)
- 上一篇: 僵尸进程孤儿进程与守护进程
- 下一篇: STL底层实现