分享

C语言有对象了

 studydoer 2019-12-16

用C的面向对象操作链表

都知道面向对象是C++/Java语言的特性,很多人只知其一不知其二,用c语言其实也是可以实现面向对象特性的,经过阅读本文之后,希望大家能更好的理解面向对象,面向对象其实是一种编程思想,与具体的语言无关,下面来看下c语言如何用面向对象的思想操作链表的。

代码:

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>

char list_name[] = "test list";

typedef struct _node{
    void* data;
    struct _nodenext;
}node_t;

typedef struct{
    const void* _;
    node_t* _head;
    int _size;
    char* _name;
}single_list_t;

typedef struct{
    int size;
    char* name;
    void* (*list_create)(void* self,va_list* params);
    void  (*list_insert)(void* self,void* data);
}list_t;

static list_t test_list={ 
    sizeof(single_list_t),
    list_name,
    list_create,
    list_insert,
};

static voidlist_create(void* _self,va_list* _params)
{
    single_list_t* self = (single_list_t*)_self;
    self->_head = (node_t*)malloc(sizeof(node_t));
    if(self->_head == NULL){printf("list_create error!\n"); return NULL;}
    self->_head->data = NULL;
    self->_head->next = NULL;
    self->_size = 0;
    self->_name = va_arg(*_params,char*);
    if(self->_name == NULL){printf("self->_name error!\n");return NULL;}

    return self;
}

static void list_insert(voidlist,void* data)
{
    single_list_t* self = (single_list_t*)list;

    node_t** p = (node_t**)&self->_head;
    for(;(*p)!=NULL;p=&(*p)->next)
        ;
    node_t* node = (node_t*)malloc(sizeof(node_t));
    node->data = data;
    node->next = NULL;
    *p = node;
    self->_size++;
    return;
}




static voidnew_object(void* _class_obj,...)
{
    list_t* class_obj = (list_t*)_class_obj;

    void* p = (void*)malloc(class_obj->size);
    if(p == NULL){return NULL;}

    *(list_t**)p = class_obj;

    if(class_obj->list_create)
    {
        va_list params;
        va_start(params,_class_obj);
        p = class_obj->list_create(p,&params);
        va_end(params);
    }

    printf("%s %s @%p\n",class_obj->name,"constructed",p);
    return p;
}

int main()
{
    single_list_t* obj_list = (single_list_t*)new_object((void*)(&test_list),"wqj");
    if(!obj_list)
    {
        printf("new_object error!\n"); 
        return -1;
    }
    char test_data[] = {"hello world"};
    list_insert((void*)obj_list,(void*)test_data);

    printf("list size:%d\n",obj_list->_size);
    printf("list 1 data:%s\n",(char*)obj_list->_head->next->data);
    return 0;
}

代码详解

/*链表节点结构体*/
typedef struct _node{
    void* data;
    struct _nodenext;
}node_t;
/*整个链表类*/
typedef struct{
    const void* _;//链表类方法指针
    node_t* _head;//链表所有元素的头
    int _size;//链表的大小
    char* _name;//链表的名字
}single_list_t;

后三个成员相当于类的成员变量。
/*方法作为一个整体的类型*/
/*对应C++中的虚表指针*/

typedef struct{
    int size;
    char* name;
    void* (*list_create)(void* self,va_list* params);//相当于c++的构造函数
    void  (*list_insert)(void* self,void* data);
}list_t;

/*定义一整套方法*/
static list_t test_list={ 
    sizeof(single_list_t),
    list_name,
    list_create,
    list_insert,
};
/*创建链表*/
static void* list_create(void* _self,va_list* _params)
{
    single_list_t* self = (single_list_t*)_self;
    self->_head = (node_t*)malloc(sizeof(node_t));
    if(self->_head == NULL){printf("list_create error!\n"); return NULL;}
    self->_head->data = NULL;
    self->_head->next = NULL;
    self->_size = 0;
    self->_name = va_arg(*_params,char*);
    if(self->_name == NULL){printf("self->_name error!\n");return NULL;}

    return self;
}

/*插入节点*/
static void list_insert(void* list,void* data)
{
    single_list_t* self = (single_list_t*)list;

    node_t** p = (node_t**)&self->_head;
    for(;(*p)!=NULL;p=&(*p)->next)
        ;
    node_t* node = (node_t*)malloc(sizeof(node_t));
    node->data = data;
    node->next = NULL;
    *p = node;//此处的p代表的是最后一个节点的成员next的地址,*p就是next成员的值
    self->_size++;
    return;
}
/*创建一个对象*/

static voidnew_object(void* _class_obj,...)
{
    list_t* class_obj = (list_t*)_class_obj;//方法集合

    /*填充链表类的成员*/

    void* p = (void*)malloc(class_obj->size);
    if(p == NULL){return NULL;}

    *(list_t**)p = class_obj;//填充方法

    if(class_obj->list_create)
    {
        va_list params;
        va_start(params,_class_obj);
        p = class_obj->list_create(p,&params);//填充成员变量
        va_end(params);
    }

    printf("%s %s @%p\n",class_obj->name,"constructed",p);
    return p;
}

至此,对C用面向对象的思想操作链表有基本认识了吗?

没有也不用急,路漫漫其修远,不停的上下求索就是了。

一个开卷有益,不停的上下求索的公众号:IT平头哥

    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约