zoukankan      html  css  js  c++  java
  • 理解迭代器

    在学习c++ STL的时候,整天碰到迭代器,也整天用,但是,到底它是个什么东西,很多人没有一个认识。这里我通过几个小的DEMO,来看看迭代器。首先我实现了一个十分简陋的vector类:
    [cpp]
    1. template <class T>
    2. class vector {
    3. private:
    4.     T* pbegin;
    5.     int n; //当前大小
    6. public:
    7.     vector() {
    8.         pbegin = new T[100]; //暂时先固定大小
    9.         n = 0;
    10.     }
    11.     T* begin() {
    12.         return pbegin;
    13.     }
    14.     void insert(T d){
    15.         pbegin[n++] = d;
    16.     }
    17.     typedef T* iterator; //vector的迭代器就是基础指针类型
    18. };
      我们知道,vector是数组实现的,也就是说,只要知道数组的首地址,就能知道后面每个元素的位置,所以,访问vector的迭代器,其实就是一个基础的指针类型,我们可以通过++,--等操作,来遍历访问该vector。
    [cpp]
    1. //测试vector
    2.     vector<int> a;
    3.     a.insert(1);
    4.     a.insert(2);
    5.     vector<int>::iterator itra;
    6.     itra = a.begin();
    7.     printf("%d/n", *itra);
    8.     itra++;
    9.     printf("%d/n", *itra);
    10.     itra--; //基础指针类型都支持++,--,+,-等操作符
    11.     printf("%d/n", *itra);
      哇~~,原来vector的迭代器那么简单,那么,我们来考虑一下List,这是链表,我们知道,链表每个元素都存储在不同的位置,我们一般通过指 向下一个元素的next指针来找到下一个元素。那么,我们怎么样来设计一个迭代器,然后可以直接对这个迭代器进行++,--等操作二遍历访问整个链表呢:
    [cpp]
    1. template <class T>
    2. class List{
    3. private:
    4.     struct Node{ //链表的节点
    5.         T data;
    6.         Node* next;
    7.     };
    8.     Node* pbegin; //表头
    9.     class List_iterator{ //链表的迭代器
    10.         Node* cur; //当前指向
    11.     public:
    12.         void operator = (Node* ptr) {
    13.             cur = ptr;
    14.         }
    15.         void operator ++ () {
    16.             cur = cur->next;
    17.         }
    18.         // ...还可以重载-- + -等操作符
    19.         T operator * (){
    20.             return cur->data;
    21.         }
    22.     };
    23. public :
    24.     List() {
    25.         pbegin=NULL;
    26.     }
    27.     Node* begin() {
    28.         return pbegin;
    29.     }
    30.     void insert(T d) {
    31.         Node* p=pbegin;
    32.         while(p && p->next) p=p->next;
    33.         Node* t = new Node;
    34.         t->data = d;
    35.         t->next = NULL;
    36.         if(pbegin==NULL)
    37.             pbegin = t;
    38.         else
    39.             p->next = t;
    40.     }
    41.     typedef List_iterator iterator; //List的迭代器是一个类
    42. };
      为List设计的迭代器是一个类,这个类支持++操作来向后移动遍历链表:
    [cpp]
    1. /测试List
    2.     List<int> b;
    3.     b.insert(1);
    4.     b.insert(2);
    5.     List<int>::iterator itrb;
    6.     itrb = b.begin();
    7.     printf("%d/n", *itrb);
    8.     itrb++; // 该迭代器只支持++
    9.     printf("%d/n", *itrb);
      通过这两个例子,可以看出,迭代器是跟容器紧密结合的,不同的容器,它的迭代器不同,但是,他们有共同的目标,就是可以通过该迭代器,来遍历访问这 个容器里面的元素。这样带来的好处是在STL设计算法时,可以脱离容器而设计更加通用的算法。比如,在容器中查找一个元素。查找,这个操作一般来说就是遍 历整个集合,然后找到那个要找的元素,但是,如果没有迭代器,我们需要为vector和List设计两个查找算法,因为找下一个元素在vector和 List中的操作不同。同样的思想却要两套代码,显然这是不优秀的。 有了模板,我们可以将算法和特定的数据分离开来,而有了迭代器,我们可以将算法和特定的容器分离开来。   作者:yxysdcl
  • 相关阅读:
    POJ-3176 Cow Bowling
    01背包、完全背包、多重背包
    最后的几天暑假学习
    暑假的学习
    凸包算法(Graham扫描法)详解
    微软版的SqlHelper.cs类
    SQL语句分组排序,多表关联排序
    SQL存储过程分页(通用的拼接SQL语句思路实现)
    增加删除字段修改字段名,修改表结构,非常用SQL语句技巧总结
    Asp.net mvc返回Xml结果,扩展Controller实现XmlResult以返回XML格式数据
  • 原文地址:https://www.cnblogs.com/benhuan/p/3302080.html
Copyright © 2011-2022 走看看