zoukankan      html  css  js  c++  java
  • C++STL之迭代器2

    在学习c++ STL的时候,整天碰到迭代器,也整天用,但是,到底它是个什么东西,很多人没有一个认识。这里我通过几个小的DEMO,来看看迭代器。首先我实现了一个十分简陋的vector类:

     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       
    12     T* begin() {  
    13         return pbegin;  
    14     }  
    15     void insert(T d){  
    16         pbegin[n++] = d;  
    17     }  
    18     typedef T* iterator; //vector的迭代器就是基础指针类型  
    19 };

    我们知道,vector是数组实现的,也就是说,只要知道数组的首地址,就能知道后面每个元素的位置,所以,访问vector的迭代器,其实就是一个基础的指针类型,我们可以通过++,--等操作,来遍历访问该vector。

     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指针来找到下一个元素。那么,我们怎么样来设计一个迭代器,然后可以直接对这个迭代器进行++,--等操作二遍历访问整个链表呢:

     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设计的迭代器是一个类,这个类支持++操作来向后移动遍历链表:

    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中的操作不同。同样的思想却要两套代码,显然这是不优秀的。

          有了模板,我们可以将算法和特定的数据分离开来,而有了迭代器,我们可以将算法和特定的容器分离开来。

    转载自:http://blog.csdn.net/yxysdcl/article/details/5567460。

  • 相关阅读:
    oracle中job定时调用存储过程的实例
    oracle recyclebin详解(闪回删除的表)
    启动和禁用约束及删除违反约束的记录
    儒轩画的老鼠
    SQLServer2005重建索引
    [转]你真的了解 console 吗
    [转]C# 理解lock
    [转]大话 程序猿 眼里的 高并发
    莆田系医院名单
    .Net WEB 程序员需要掌握的技能
  • 原文地址:https://www.cnblogs.com/balingybj/p/4712208.html
Copyright © 2011-2022 走看看