iterator到底是不是pointer? (转载)

转载自  http://www.cnblogs.com/oomusou/archive/2008/07/21/stl_iterator_pointer.html

 

Abstract
使用iterator時,能使用pointer的*、++、--與->等操作,到底iterator是不是pointer呢?

Introduction
一個很典型使用vector的STL程式碼。

1   #include < vector >
2   #include < iostream >
3  
4   using   namespace std;
5  
6   int main() {
7     vector < int > ivec;
8     ivec.push_back( 1 );
9     ivec.push_back( 2 );
10     ivec.push_back( 3 );
11     ivec.push_back( 4 );
12    
13     for (vector < int > ::iterator iter = ivec.begin(); iter != ivec.end(); ++ iter)
14       cout <<   * iter << endl;
15   }


執行結果

1
2
3
4


13行

1   for (vector < int > ::iterator iter = ivec.begin(); iter != ivec.end(); ++ iter)
2     cout <<   * iter << endl;


iterator有兩個很神奇的操作:++iter與*iter,怎麼看都像在操作pointer,那到底iterator是不是pointer呢?

學C++的人大概分兩種背景的族群:
1.原來會C,有pointer概念

看 到iterator的*、++、--與->等操作,一定會認為iterator就是個pointer,但我翻遍了C++ Primer 4th,就是沒看到它肯定地說『iterator就是poiner』,或說『iterator不是pointer』,留下一個曖昧的想像空間。若以C語言 思考,iterator『應該』是pointer。

2.原來會C#、Java,有OO概念
『Everthing is object』,int是object,vector是object,所所以iterator『應該』也是object,但是iterator為什麼能 用*、++、--與->等操作呢?那只是因為operator overloading的原因。況且C++對於pointer幾乎都有新的解決方案,如reference取代pass by pointer、vector取代array、string取代char *、STL containter取代dynamic alloction..等(請參閱(原創) C/C++哪些地方會用到pointer呢? (C/C++) (C) )。 若以OO思維思考,iterator『應該』不是pointer。

到底誰說的才對呢?所謂『有code有真相』,我們直接拿SGI STL的source code來看看最常用的vector與list的iterator是如何實現。(我並沒有包含完整的SGI STL source,只截取我要解釋的部分來說明)。

stl_vector.h / C++

1   template < class T >
2   class vector {
3   public :
4     typedef T value_type;
5     typedef value_type * iterator; // pointer to T
6   }


5行

typedef value_type * iterator; // pointer to T


這裡很明顯,vector的iterator就是個pointer,看你T是什麼型別,就是指向T的pointer,所以對vector的iterator來說,它完全是一個pointer 。 C語言背景的pointer概念在vector是正確的。

stl_list.h / C++

1   template < class T >
2   struct __list_node {
3     __list_node < T >   * void_pointer;
4     void_pointer prev;
5     void_pointer next;
6     T data;
7   };
8    
9   template < class T, class Ref, class Ptr >
10   struct __list_iterator {
11     typedef Ref reference;
12     typedef Ptr pointer;
13     typedef __list_iterator < T, Ref, Ptr > self;
14     typedef __list_node < T >   * link_type;
15     link_type node; // pointer to node
16    
17     reference operator * () const {
18       return ( * node).data;
19     }
20    
21     pointer operator -> () const {
22       return   & ( operator * ());
23     }
24    
25     self &   operator ++ () {
26       node = (link_type)(( * node).next);
27       return   * this ;
28     }
29    
30     self operator -- () {
31       node = (link_type)(( * node).prev);
32       return   * this ;
33     }
34   };
35  
36   template < class T >
37   class list {
38   public :     
39   typedef __list_iterator < T, T & , T *>   iterator;
40   };


39行

typedef __list_iterator < T, T & , T *>   iterator;


list的iterator是__list_iterator的typedef,所以要繼續追__list_iterator是什麼東西。

9行

template < class T, class Ref, class Ptr >
struct __list_iterator {
  typedef Ref reference;
  typedef Ptr pointer;
  typedef __list_iterator
< T, Ref, Ptr > self;
  typedef __list_node
< T >   * link_type;
  link_type node;
// pointer to node
 
  reference
operator * () const {
   
return ( * node).data;
  }
 
  pointer
operator -> () const {
   
return   & ( operator * ());
  }
 
  self
&   operator ++ () {
    node
= (link_type)(( * node).next);
   
return   * this ;
  }
 
  self
operator -- () {
    node
= (link_type)(( * node).prev);
   
return   * this ;
  }
};


__list_iterator是定義list iterator的class, 所以OO背景說的沒錯,iterator不是pointer,它只是一個object ,iterator的*、->、++、--都是operator overloading做出來的,而不是pointer本身的操作。 在++與--中,我們看到了node,node是什麼東西呢?繼續追下去...

14行

typedef __list_node < T >   * link_type;
link_type node;
// pointer to node


我們知道list其實是資料結構的double linked list,由node所構成, 所以iterator的所有操作,本質上都是在操作node,再來看__list_node是如何定義的。

2行

template < class T >
struct __list_node {
  __list_node
< T >   * void_pointer;
  void_pointer prev;
  void_pointer next;
  T data;
};


__list_node 利用prev與next指向前一個node與後一個node,prev和next都是pointer,是個指向__list_node<T> 的pointer,所以__list_iterator的++、--最後是靠pointer沒錯,不過list的iterator本身並不是 pointer,而是個object,只是它用operator overloading模擬了pointer的操作而已。

Conclusion
iterator是不是pointer呢?要看container而定,由上可知,vector的iterator是pointer,list的iterator就不是pointer , 而是object利用operator overloading使它表面上的操作像pointer而已,但並不是一個pointer。所以C語言背景與OO背景的人都是瞎子摸象,只摸到 iterator的一部分。iterator除了因為vector因為較簡單,所以使用native pointer外,其他container的interator都是一種smart pointer,因為其操作跟pointer一樣,你可以將它當成pointer方式使用,不過他仍然不是pointer

iterator 是泛型編程一個重要的概念,container只需知道如何使用iterator(*、++、--、->)即可,完全不需知道iterator的實 際型別,而演算法可以完全獨立於container與iterator自行發展,只要設計時以iterator為對外interface即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值