| 作者 |
内容 |
| qliang1 |
HELP:
Iterator能写成通用的吗?
Iterator为了重用,不惜写成模板类,以便不知道自己遍历的是什么东西。可如果构造他(iterator)的参数不是个数组,他还是要知道如何获取遍历目标的第一个或下一个,看来知道还是不可避免。
GO4的书里举的例子一下子就用STL的List初始化ListIterator,后来ListIterator的First/Next/Current自然好写得一塌糊涂,因为作者认为大家都该知道STL
List有个Get(int current_index)方法(//我咋就不知道呢:))。
有趣的地方就在这儿。好像STL怎么包装数组或链表的细节就没人管了。而写这个ListIterator本身就是在处理细节。
简单地说,我的问题是:Iterator不可避免地要知道自己所遍历的element的一些细节(请注意,是方法名,很严重了),是不是?如果是这样,通用性何在?
//note:请别用纯数组举例了,哪怕用个链表你也会体会问题的必要性。
谢谢!
|
| 03/10/09 14:24 |
酷帖! 臭帖! 回复 |
|
酷帖评价: 臭帖评价: |
| 返回页首 |
|
| smilemac |
如果能,还要迭代器干什么?:-)
有点想象力,呵呵。
iterator不需要知道element的细节,它需要知道的是container的细节:-) |
| 03/10/09 18:32 |
酷帖! 臭帖! 回复 |
|
酷帖评价: 臭帖评价: |
| 返回页首 |
|
| frankwoo |
回复:
HELP: Iterator能写成通用的吗?
smilemac已经说了。
找个STL的代码看看
就明白了。 |
| 03/10/09 21:56 |
酷帖! 臭帖! 回复 |
|
酷帖评价: 臭帖评价: |
| 返回页首 |
|
| qliang1 |
回复:
如果能,还要迭代器干什么?:-)
那container要知道element的细节喽? |
| 03/10/10 04:27 |
酷帖! 臭帖! 回复 |
|
酷帖评价: 臭帖评价: |
| 返回页首 |
|
| sealw |
通用性在于,使用Iterator的代码不需要知道容器的内部组织结构
写成模板类不是为了让Iterator不知道自己遍历的是什么,而是为了类型安全以及少写一些强制类型转换代码
您可以在开始设计时写出
Iterator it = vector.iterator();
然后在以后的设计中将其改为
Iterator it = veryComplexContainer.iterator();
然后客户部分代码都不需要改动。甚至这部分的代码改动也可以隔离掉,写成
Iterator it = objectFactory.getCandyIterator();
所有的变化都集中在了objectFactory的实现中,而在那个实现里,内部是高内聚的。但对于外部的客户代码,则是低耦合的。
Iterator本身一定知道自己要遍历的容器的组织结构,而向容器的使用者提供了一个低耦合的Iterator接口,从而将变化局限在了局部代码之中。 |
| 03/10/10 09:00 |
酷帖! 臭帖! 回复 |
|
酷帖评价: 臭帖评价: |
| 返回页首 |
|
| smilemac |
不需要。
|
| 03/10/10 09:29 |
酷帖! 臭帖! 回复 |
|
酷帖评价: 臭帖评价: |
| 返回页首 |
|
| qliang1 |
如果元素本身是有结构的呢?比如链表,二叉树,不知道其细节能构造Container/Iterator吗?
如果元素是数组,那是不需要知道的,只要知道类型名就可以。类模板就搞定了。
可我们不能勒令客户采用一种简单结构或始终用STL或Java里的Vector等把结构弄得已经很完美。Suppose他们就是像我一样的Rookie,自己写了个符合工程要求的数据结构,现在又在想不改动它的前提下用一个外边的Iterator遍历它。
我觉得知道它的细节是不可避免的。 |
| 03/10/10 09:51 |
酷帖! 臭帖! 回复 |
|
酷帖评价: 臭帖评价: |
| 返回页首 |
|
| smilemac |
可以。
容器本身是不需要了解元素是什么的,哪怕这个元素是另外一个容器。 |
| 03/10/10 09:55 |
酷帖! 臭帖! 回复 |
|
酷帖评价: 臭帖评价: |
| 返回页首 |
|
| qliang1 |
老大是在解释工厂模式的好处了
Iterator是可以被Factory一把,但这里说的是Iterator能否被独立出来的问题啊。要是Iterator必须知道Container的细节,那么下次遍历别的Container时,岂不要重写?
老大的意思我心领。假想只有一个具体的Iterator,比如Preorder,能独立地被写出来吗?(这里我们姑且不管以后还写什么别的Iterator的问题,也就无工厂模式的考虑了) |
| 03/10/10 10:07 |
酷帖! 臭帖! 回复 |
|
酷帖评价: 臭帖评价: |
| 返回页首 |
|
| qliang1 |
我只给个二叉树的根给你构造PreorderIterator,不告诉你得到左孩子的方法名叫left(),你写得出这个遍历器的Next()方法吗?
??? |
| 03/10/10 10:11 |
酷帖! 臭帖! 回复 |
|
酷帖评价: 臭帖评价: |
| 返回页首 |
|
| smilemac |
回复:
我只给个二叉树的根给你构造PreorderIterator,不告诉你得到左孩子的方法名叫left(),你写得出这个遍历器的Next()方法吗?
我前面已经告诉你了,iterator必须知道container的细节,不存在独立于container的iterator,或者说,一个iterator必须依存某个container存在,统一的是iteraor的接口,不是实现。 |
| 03/10/10 10:17 |
酷帖! 臭帖! 回复 |
|
酷帖评价: 臭帖评价: |
| 返回页首 |
|
| qliang1 |
那就是说,具体的Iterator(比如二叉树Preorder)想能被复用,只要保证Container提供一致的构造该Iterator所需的方法就可以了?
看来还是能通用的,就是要求container规整一点,最好满足一个方法接口。 |
| 03/10/10 10:37 |
酷帖! 臭帖! 回复 |
|
酷帖评价: 臭帖评价: |
| 返回页首 |
|
| smilemac |
Iterator就是這個接口,如果container另外有這樣通用接口,就不需要iterator這個接口了。
你沒看懂我第一個回復的意思嗎? |
| 03/10/10 10:43 |
酷帖! 臭帖! 回复 |
|
酷帖评价: 臭帖评价: |
| 返回页首 |
|
| sealw |
不能。container如何组织element的细节必须有某个类知道,通常就是由container的iterator方法返回一个类来知道这方面的信息,这个类实现iterator接口。
您可能对Iterator的设计意图不很了解。 |
| 03/10/10 18:18 |
酷帖! 臭帖! 回复 |
|
酷帖评价: 臭帖评价: |
| 返回页首 |
|