C语言实现容器

你。 提交于 2020-01-24 23:01:07

实现思路

最近在看Redis源代码,发现了许多自己不知道的C语言的书写方式,这些写法可以实现许多结构。
CXX使用泛型提供了容器,但是C语言中不允许将数据类型作为参数进行传递,所以我们必须使用另一种方式来实现我们的目的结构。

typedef struct listNode {
    struct listNode *prev;
    struct listNode *next;
    void *value;
} listNode;

typedef struct listIter {
    listNode *next;
    int direction;
} listIter;

typedef struct list {
    listNode *head;    
    listNode *tail;    
    void *(*dup)(void *ptr);   
    void (*free)(void *ptr);
    int (*match)(void *ptr, void *key);
    unsigned long len;   
} list;

list *listCreate(void);    // 创建
void listRelease(list *list);   // 删除
list *listAddNode(list *list, void *value); // 添加
listNode *listSearchKey(list *list, void *key);  // 查找

Redis使用这种定义结构实现容器的定义,我们可以看到容器内部的数据使用void *value去指向,而我们的容器中包含四个函数void *(*dup)(void *ptr)void (*free)(void *ptr)int (*match)(void *ptr, void *key)void (*print)(void *ptr)。每当我们需要操作容器内部的数据value时,我们就调用这个函数指针对应的方法进行操作,这样就实现了不同的数据类型能够达到不同的操作的方式。
其中我们看到我们给出了free函数,因为我们释放链表节点的同时我们需要释放其value *所指向内容的地址空间,然而这个结构可能还引用了其他的结构,所以我们必须手动提供一个free函数,来指导链表正确释放所指向的空间。
从中我们也能看到,CPP中析构函数的动态顺序也符合这个顺序,先析构子成员再析构自身。
完整示例

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!