前面我们介绍了如何在 C 语言中引入面向对象语言的一些特性来进行面向对象编程,从本篇开始,我们使用前面提到的技巧,陆续实现几个例子,最后呢,会提供一个基本的 http server 实现(使用 libevent )。在这篇文章里,我们实现一个通用的数据结构:单链表。
这里实现的单链表,可以存储任意数据类型,支持增、删、改、查找、插入等基本操作。(本文提供的是完整代码,可能有些长。)
下面是头文件:
#ifndef SLIST_H
#define SLIST_H
#ifdef __cplusplus
extern "C" {
#endif
#define NODE_T(ptr, type) ((type*)ptr)
struct slist_node {
struct slist_node * next;
};
typedef void (*list_op_free_node)(struct slist_node *node);
/*
* return 0 on hit key, else return none zero
*/
typedef int (*list_op_key_hit_test)(struct slist_node *node, void *key);
struct single_list {
/* all the members must not be changed manually by callee */
struct slist_node * head;
struct slist_node * tail;
int size; /* length of the list, do not change it manually*/
/* free method to delete the node
*/
void (*free_node)(struct slist_node *node);
/*
* should be set by callee, used to locate node by key(*_by_key() method)
* return 0 on hit key, else return none zero
*/
int (*key_hit_test)(struct slist_node *node, void *key);
struct single_list *(*add)(struct single_list * list, struct slist_node * node);
struct single_list *(*insert)(struct single_list * list, int pos, struct slist_node *node);
/* NOTE: the original node at the pos will be freed by free_node */
struct single_list *(*replace)(struct single_list *list, int pos, struct slist_node *node);
struct slist_node *(*find_by_key)(struct single_list *, void * key);
struct slist_node *(*first)(struct single_list* list);
struct slist_node *(*last)(struct single_list* list);
struct slist_node *(*at)(struct single_list * list, int pos);
struct slist_node *(*take_at)(struct single_list * list, int pos);
struct slist_node *(*take_by_key)(struct single_list * list, void *key);
struct single_list *(*remove)(struct single_list * list, struct slist_node * node);
struct single_list *(*remove_at)(struct single_list *list, int pos);
struct single_list *(*remove_by_key)(struct single_list *list, void *key);
int (*length)(struct single_list * list);
void (*clear)(struct single_list * list);
void (*deletor)(struct single_list *list);
};
struct single_list * new_single_list(list_op_free_node op_free, list_op_key_hit_test op_cmp);
#ifdef __cplusplus
}
#endif
#endif // SLIST_H
struct single_list 这个类,遵循我们前面介绍的基本原则,不再一一细说。有几点需要提一下:
- 我们定义了 slist_node 作为链表节点的基类,用户自定义的节点,都必须从 slist_node 继承
- 为了支持节点( node )的释放,我们引入一个回调函数 list_op_free_node ,这个回调需要在创建链表时传入
- 为了支持查找,引入另外一个回调函数 list_op_key_hit_test
好了,下面看实现文件:
#include "slist.h"
#include <malloc.h>
static struct single_list * _add_node(struct single_list *list, struct slist_node *node)
{
if(list->tail)
{
list->tail->next = node;
node->next = 0;
list->tail = node;
list->size++;
}
else
{
list->head = node;
list->tail = node;
node->next = 0;
list->size &