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

/**

*C语言模拟go语言对多态的实现

*定义一个接口,一个类实现了该接口的所有函数,

*则这个类即为该接口的实现,不显式声明一个类实现的接口

*

*在C语言中,则定义一个包含一组函数指针的结构体模拟接口

*子类有一个创建该结构体的函数,则表示该子类实现接口

*/

#include

#include

#include

#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;

}

参考:

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

有疑问加站长微信联系(非本文作者)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值