您的位置:首页 > 其它

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

2011-01-18 13:38 447 查看
转载自 /article/6947280.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即可。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: