C++ 迭代器原理、失效和實現

來源:互聯網
上載者:User

標籤:技術   tor   tmp   ace   四種   height   lock   map   next   

目錄
  1. 迭代器的使用
  2. 迭代器的種類
  3. 迭代器的失效
  4. 迭代器的實現
1.迭代器的使用

       為了提高C++編程的效率,STL中提供了許多容器,包括vector、list、map、set等。有些容器例如vector可以通過腳標索引的方式訪問容器裡面的資料,但是大部分的容器不能使用這種方式,例如list、map、set。STL中每種容器在實現的時候設計了一個內嵌的iterator類,不同的容器有自己專屬的迭代器,使用迭代器來訪問容器中的資料。除此之外,通過迭代器,可以將容器和通用演算法結合在一起,只要給予演算法不同的迭代器,就可以對不同容器執行相同的操作,例如find尋找函數。迭代器對指標的一些基本操作如*、->、++、==、!=、=進行了重載,使其具有了遍曆複雜資料結構的能力,其遍曆機製取決於所遍曆的資料結構,所有迭代的使用和指標的使用非常相似。通過begin,end函數擷取容器的頭部和尾部迭代器,end 迭代器不包含在容器之內,當begin和end返回的迭代器相同時表示容器為空白。

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);//定義容器vector    list<int> iList(arr, arr + 5);//定義容器list    //在容器iVec的頭部和尾部之間尋找整形數3    vector<int>::iterator iter1 = find(iVec.begin(), iVec.end(), 3);    if (iter1 == iVec.end())        cout<<"3 not found"<<endl;    else        cout<<"3 found"<<endl;    //在容器iList的頭部和尾部之間尋找整形數4    list<int>::iterator iter2 = find(iList.begin(), iList.end(), 4);    if (iter2 == iList.end())        cout<<"4 not found"<<endl;    else        cout<<"4 found"<<endl;    return 0;}
2.迭代器的種類

根據迭代器所支援的操作,可以把迭代器分為5類。

1)   輸入迭代器:是唯讀迭代器,在每個被遍曆的位置上只能讀取一次。例如上面find函數參數就是輸入迭代器。

2)   輸出迭代器:是唯寫迭代器,在每個被遍曆的位置上只能被寫一次。

3)   前向迭代器:兼具輸入和輸出迭代器的能力,但是它可以對同一個位置重複進行讀和寫。但它不支援operator--,所以只能向前移動。

4)   雙向迭代器:很像前向迭代器,只是它向後移動和向前移動同樣容易。

5)   隨機訪問迭代器:有雙向迭代器的所有功能。而且,它還提供了“迭代器算術”,即在一步內可以向前或向後跳躍任意位置,  包含指標的所有操作,可進行隨機訪問,隨意移動指定的步數。支援前面四種Iterator的所有操作,並另外支援it + n、it - n、it += n、 it -= n、it1 - it2和it[n]等操作。

STL每種容器類型都定義了 const_iterator,只能讀取容器的值,不能修改所指向容器範圍內元素的值。vector、string、Deque隨機存取迭代器;List、Set、map、mutiset、multimap雙向迭代器。

3.迭代器失效

容器的插入insert和erase操作可能導致迭代器失效,對於erase操作不要使用操作之前的迭代器,因為erase的那個迭代器一定失效了,正確的做法是返回刪除操作時候的那個迭代器。

#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.迭代器的實現

STL中每個容器都有自己的迭代器,各種迭代器的介面相同,內部實現卻不相同,這也直接體現了泛型程式設計的概念,下面在單鏈表類中內嵌入一個iterator的類來實現單鏈表的迭代

  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     //內建迭代器 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     //其它成員函數 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 }

 

參考: http://blog.csdn.net/shudou/article/details/11099931

C++ 迭代器原理、失效和實現

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.