C语言面向对象的通用链表实现

C语言面向对象的通用链表实现

将接头体看做类似C++中的类,在里面声明数据和方法。其中包括一个链表所必须的数据和操作链表所必须的方法,再定义一个接口用于创建链表。使用指针的原因是防止局部变量被释放掉。

typedef struct node_t Node;
struct node_t
{
    void *data;
    Node *next;
};

typedef struct 
{
    void (*user_data_free)(void *data);                         // 用户释放数据,不包含*data的释放
    int (*node_compare)(void *node_data, void *data);           // 用户数据和节点数据比较,相等返回0
} clist_user_hooks_t;

typedef struct list_t List;
struct list_t
{
    Node *head;
    Node *tail;
    int size;

    clist_user_hooks_t user_hooks;

    /* private */
    int (*delete_node)(List *plist, Node *pnode);
    Node * (*create_node)(List *plist, void *data, size_t size);

    /* public */
    void (*clist_delete_list)(List *plist);
    int (*node_add)(List *plist, void *data, size_t size);
    int (*node_del)(List *plist);
    int (*node_del_by_data)(List *plist, void *data, int (*p_traverse)(void *node_data, void *data));
    void * (*clist_get_data_by_index)(List *plist, int index);
    void * (*clist_get_data_by_data)(List *plist, void *data, int (*p_traverse)(void *node_data, void *data));
    int (*clist_get_index_by_data)(List *plist, void *data, int (*p_traverse)(void *node_data, void *data));
    int (*clist_traverse_list)(List *plist, void *data, int (*p_traverse)(void *node_data, void *data));
};

List * clist_new_list(clist_user_hooks_t *hooks);

实现上面的声明的所有方法。
然后通过函数指针来把这些方法作为List类的方法实现。

例如,实现遍历链表的方法:如下

int clist_traverse_list(List *plist, void *data, int (*p_traverse)(void *node_data, void *data))
{
    CLIST_CHECK_PTR_NULL(plist);

    Node *pnode = plist->head;
    for (; pnode != NULL; pnode = pnode->next)
    {
        p_traverse(pnode->data, data);
    }

    return CLIST_OK;
}

clist_new_list中进行挂载。

user_hooks则作为用户钩子来调用用户的接口。因此,需要在创建链表时,传入用户回调,以便在链表操作中使用。

List * clist_new_list(clist_user_hooks_t *user_hooks)
{
    if (user_hooks == NULL || user_hooks->user_data_free == NULL || user_hooks->node_compare == NULL)
        return NULL;

    List *plist = (List *)malloc(sizeof(List));
    if (plist == NULL) {
        return NULL;
    }

    plist->head = NULL;
    plist->tail = NULL;
    plist->size = 0;

    plist->user_hooks.user_data_free = user_hooks->user_data_free;
    plist->user_hooks.node_compare = user_hooks->node_compare;

    plist->create_node = clist_create_node;
    plist->delete_node = clist_delete_node;

    plist->clist_delete_list = clist_delete_list;
    plist->node_add = clist_node_add;
    plist->node_del = clist_node_del;
    plist->node_del_by_data = clist_node_del_by_data;
    plist->clist_get_data_by_data = clist_get_data_by_data;
    plist->clist_get_data_by_index = clist_get_data_by_index;
    plist->clist_get_index_by_data = clist_get_index_by_data;
    plist->clist_traverse_list = clist_traverse_list;

    return plist;
}

如果相对链表中的方法和类进行扩充或改写的话,可以使用结构体嵌套来实现继承。

clist_user_hooks_t hooks = {
    .user_data_free = free_conf_item,
    .node_compare = compare_conf_item};

List *fconf_list = clist_new_list(&hooks);
if (!fconf_list)
{
    return 4;
}

NewList *newList;
newList->newList = fconf_list;
newList->clist_sort = fconf_sort;

List *p_newList  = (List *)newList;
p_newList->node_add(p_newList, data, sizeof(data));
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值