Chinaunix首页 | 论坛 | 博客
  • 博客访问: 30425
  • 博文数量: 11
  • 博客积分: 405
  • 博客等级: 一等列兵
  • 技术积分: 215
  • 用 户 组: 普通用户
  • 注册时间: 2012-05-14 11:53
文章分类
文章存档

2012年(11)

我的朋友

分类: C/C++

2012-05-22 15:31:17

 
创建函数
  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) |
给主人留下些什么吧!~~