创建函数
Iterator* dlist_iterator_create(DList* dlist)
{
Iterator* thiz = NULL;
return_val_if_fail(dlist != NULL, NULL);
if((thiz = malloc(sizeof(Iterator) + sizeof(PrivInfo))) != NULL)
{
PrivInfo* priv = (PrivInfo*)thiz->priv;
thiz->set = dlist_iterator_set;
thiz->get = dlist_iterator_get;
thiz->next = dlist_iterator_next;
thiz->prev = dlist_iterator_prev;
thiz->advance = dlist_iterator_advance;
thiz->clone = dlist_iterator_clone;
thiz->offset = dlist_iterator_offset;
thiz->destroy = dlist_iterator_destroy;
priv->dlist = dlist;
priv->cursor = dlist->first;
priv->offset = 0;
}
return thiz;
}
这里我们还遇到另外一个难题:双向链表的迭代器的实现放在哪里?放在dlist.c里还是单独的文件里呢,放在单独的文件里可读性更强,但是在访问双向链表的内部数据时会遇到一些麻烦。最后的选择如下。
(1) dlist_iterator.h提供独立的文件。
(2) dlist_iterator.c也提供独立的文件,但是它不直接参与编译,而是在dlist.c里include它。
这样就两全其美了:维护方便又可以访问双向链表的内部数据结构。
最后我们来看看用迭代器实现的invert函数。
Ret invert(Iterator* forward, Iterator* backward)
{
void* data1 = NULL;
void* data2 = NULL;
return_val_if_fail(forward != NULL && backward != NULL, RET_INVALID_PARAMS);
for(; iterator_offset(forward) < iterator_offset(backward);
iterator_next(forward), iterator_prev(backward))
{
iterator_get(forward, &data1);
iterator_get(backward, &data2);
iterator_set(forward, data2);
iterator_set(backward, data1);
}
return RET_OK;
}
invert算法同时适用于双向链表和动态数组,而且它们的运行效率相差不大,至少对于双向链表来说已经是比较高效的实现了。
迭代器模式是一种重要的模式,在C++的标准模板库(STL)中有大量的应用。老的C程序员通常是运行效率至上的,所以要在优雅的设计和高性能之间做出选择时,他们通常选择后者,所以很少看到C语言实现的容器提供迭代器,那也不足为奇。重要的是我们可以学习这种方法,并在适当的时候运用它。更多文章
http://faniechu.blog.chinaunix.net
阅读(250) | 评论(0) | 转发(0) |