模仿go语言的C语言面向对象范式

/**
*C语言模拟go语言对多态的实现
*定义一个接口,一个类实现了该接口的所有函数,
*则这个类即为该接口的实现,不显式声明一个类实现的接口
*
*在C语言中,则定义一个包含一组函数指针的结构体模拟接口
*子类有一个创建该结构体的函数,则表示该子类实现接口
*/

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

#ifndef SAFE_FREE
#define SAFE_FREE(p) \
do \
{ \
    free(p); \
    p = NULL; \
} while (0)
#endif //SAFE_FREE

/**
*定义接口
*cthis是一个指针,指向实现该接口的类
*eat是接口包含的函数(函数指针)
*/
typedef struct _i_animal
{
    void *cthis;
    void (*eat)(void *cthis);
} i_animal;

/**
*数据类型rabbit
*含有一个属性name
*/
typedef struct _rabbit
{
    char *name;
} rabbit;

/**
*rabbit实现i_animal接口需要的函数
*/
void rabbit_eat(void *cthis)
{
    printf("%s eat!\n", ((rabbit*)cthis)->name);
}

/**
*表示rabbit实现了i_animal接口
*该函数返回rabbit对接口i_animal的实现
*/
i_animal *rabbit_i_animal(void *cthis)
{
    i_animal *instance = (i_animal*)malloc(sizeof(i_animal));
    if (NULL == instance)
    {
        return NULL;
    }
    memset(instance, 0, sizeof(i_animal));
    instance->cthis = cthis;
    instance->eat = rabbit_eat;
    return instance;
}

/**
*rabbit的构造函数
*/
rabbit *rabbit_create(void)
{
    int nameLength = 10;
    rabbit *instance = (rabbit*)malloc(sizeof(rabbit));
    if (NULL == instance)
    {
        return NULL;
    }
    memset(instance, 0, sizeof(rabbit));
    instance->name = (char*)malloc(nameLength*sizeof(char));
    if (NULL != instance->name)
    {
        memset(instance->name, 0, nameLength*sizeof(char));
        strcpy(instance->name, "rabbit");
    }
    return instance;
}

/**
*rabbit的析构函数
*/
void rabbit_release(rabbit *cthis)
{
    SAFE_FREE(cthis->name);
    SAFE_FREE(cthis);
}

/**
*数据类型cat
*含有一个属性name
*/
typedef struct 
{
    char *name;
} cat;

/**
*cat实现i_animal接口需要的函数
*/
void cat_eat(void *cthis)
{
    printf("%s eat!\n", ((cat*)cthis)->name);
}

/**
*表示cat实现了i_animal接口
*该函数返回cat对接口i_animal的实现
*/
i_animal *cat_i_animal(void *cthis)
{
    i_animal *instance = (i_animal*)malloc(sizeof(i_animal));
    if (NULL == instance)
    {
        return NULL;
    }
    memset(instance, 0, sizeof(i_animal));
    instance->cthis = cthis;
    instance->eat = cat_eat;
    return instance;
}

/**
*cat的构造函数
*/
cat *cat_create(void)
{
    int nameLength = 10;
    cat *instance = (cat*)malloc(sizeof(cat));
    if (NULL == instance)
    {
        return NULL;
    }
    memset(instance, 0, sizeof(cat));
    instance->name = (char*)malloc(nameLength*sizeof(char));
    if (NULL != instance->name)
    {
        memset(instance->name, 0, nameLength*sizeof(char));
        strcpy(instance->name, "cat");
    }
    return instance;
}

/**
*cat的析构函数
*/
void cat_release(cat *cthis)
{
    SAFE_FREE(cthis->name);
    SAFE_FREE(cthis);
}

/**
*主函数
*/
int main()
{
    // 用于循环遍历的变量
    int i = 0;
    // 数组的长度
    int animals_length = 2;

    // 创建rabbit实例
    rabbit *rabbit_instance = rabbit_create();
    // 创建cat实例
    cat *cat_instance = cat_create();

    // 保存接口实现的数组 
    i_animal *animals[2] = {NULL};

    // 创建rabbit对接口i_animal的实现
    animals[0] = rabbit_i_animal(rabbit_instance);
    // 创建cat对接口i_animal的实现
    animals[1] = cat_i_animal(cat_instance);

    // 模拟多态
    for (i = 0; i < animals_length; ++i)
    {
        // 空指针判断
        if (NULL == animals[i])
        {
            continue;
        }
        // 同一段代码,不同绑定,结果会不同
        animals[i]->eat(animals[i]->cthis);
        // 接口由子类对应函数创建,需要手动释放
        SAFE_FREE(animals[i]);
    }

    // 析构rabbit
    rabbit_release(rabbit_instance);
    // 析构cat
    cat_release(cat_instance);
    return 0;
}


参考:

1、《我所偏爱的C语言面向对象编程范式》 云风的 BLOG

2、《Go语言初步》 云风的 BLOG

3、《俺使用的C语言面向对象范式

4、《Go For C++ Programmers(C++程序员指南)

5、《OO in C(1): C语言中的类模拟和多态,继承

6、《C语言面向对象的实现---多态性

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值