周立功教授谈迭代器模式设计
t函数让迭代器指向容器的下一个数据,pfn_prev函数让迭代器指向容器的上一个数据。
此时,应该针对接口编写一些获取或设置数值的方法。用于读取变量的方法通常称为"获取方法(getter)",用于写入变量的方法通常称为"设置方法(setter)"。下面以双向链表为例,使用结构体指针作为dlist_iterator_if_get()的返回值,详见程序清单3.51。
程序清单3.51 获取双向链表的迭代器接口(1)
1 static void __dlist_iterator_next(iterator_t *p_iter) // 让迭代器指向容器的下一个数据
2 {
3 *p_iter = ((dlist_node_t *)*p_iter) -> p_next;4 }
5
6 static void __dlist_iterator_prev(iterator_t *p_iter) // 让迭代器指向容器的上一个数据
7 {
8 *p_iter = ((dlist_node_t *)*p_iter) -> p_prev;
9 }
1011 iterator_if_t *dlist_iterator_if_get (void)
12 {
13 static iterator_if_t iterator_if;
14 iterator_if.pfn_next = __dlist_iterator_next;
15 iterator_if.pfn_prev = __dlist_iterator_prev;
16 return &iterator_if; // 返回结构体变量地址&iterator_if
17 }其调用形式如下:
iterator_if_t *p_if = dlist_iterator_if_get(); // 获得链表的迭代器接口,即p_if = &iterator_if
注意,如果省略static,则iterator_if就成了一个局部变量。由于它将在函数执行完后失效,因此返回它的地址毫无意义。这里采用了直接访问结构体成员的方式对iterator_if_t类型的结构体赋值,显然不同模块之间应该尽可能避免这种方式,取而代之的是提供相应的接口,详见程序清单 3.52。
程序清单 3.52 获取双向链表的迭代器接口(2)
1 void dlist_iterator_if_get(iterator_if_t *p_if)
2 {
3 p_if -> pfn_next = __dlist_iterator_next;
4 p_if -> pfn_prev = __dlist_iterator_prev;
5 }其调用形式如下:
iterator_if_t iterator_if;
dlist_iterator_if_get(&iterator_if);由于iterator_if_t类型的结构体中只有两个函数指针,因此对函数指针的访问仅包含设置和调用,详见程序清单 3.53。
程序清单 3.53 迭代器接口(iterator.h)
1 #pragma once;
2
3 typedef void *iterator_t;
4 typedef void(*iterator_next_t)(iterator_t *p_iter);
5 typedef void(*iterator_prev_t)(iterator_t *p_iter);6
7 typedef struct _iterator_if{
8 iterator_next_t pfn_next; // 调用迭代器后移的函数指针,相当于p1++
9 iterator_prev_t pfn_prev; // 调用迭代器前移的函数指针,相当于p2--
10 }iterator_if_t;
1112 void iterator_if_init(iterator_if_t *p_if, iterator_next_t pfn_next, iterator_prev_t pfn_prev);
13 void i
- 电源软启动的实用设计技巧(07-16)
- 周立功:动态分布内存——malloc()函数与calloc()函数(07-22)
- 周立功“程序设计与数据结构”:深度解剖动态分布内存的free()函数与realloc()函数(07-25)
- 周立功教你学程序设计技术:做好软件模块的分层设计,回调函数要这样写(07-30)
- 周立功教你学C语言编程:教你数组是如何保存指针的(07-31)
- 算法的泛化问题,这些坑你可能都经历过!|周立功教你学软件设计(08-01)