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即可。
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即可。
相关文章推荐
- (原創) iterator到底是不是pointer? (C/C++) (STL)
- Racket,你到底是不是Scheme啊?
- 【转载】知识普及:天煞的HTML5到底是个什么东西
- “借贷宝”到底是不是坑?——“借贷宝”注册送现金营销模式分析?【已亲测可以无条件提现成功】
- 到底是不是太胖了(卡精度)
- 大预言:房价将下跌40%~60% 2010年到底(转载)
- 普通高中生水平就能干好的编程到底是不是高科技?-张孝祥
- 设计模式Iterator(迭代器) (转载)
- 普通高中生水平就能干好的编程到底是不是高科技?
- const char* ptr 到底是什么意思【转载的,从此不再蛋疼】
- STM32 硬件I2C 到底是不是个坑?
- 比特币到底是不是货币?
- 到底是不是太胖了
- L1-031 到底是不是太胖了
- 【转】内核编译时, 到底用make clean, make mrproper还是make distclean(转载)
- L1-031. 到底是不是太胖了
- JVM学习(2)——技术文章里常说的堆,栈,堆栈到底是什么,从os的角度总结--转载http://www.cnblogs.com/kubixuesheng/p/5202561.html
- 【转载】ORM的概念, ORM到底是什么
- 八一八:飞行汽车到底是不是一个伪命题
- (转载) 到底什么样的杀毒软件好