模仿go语言的C语言面向对象范式
2012-02-05 10:20
274 查看
/** *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语言面向对象的实现---多态性》
相关文章推荐
- 模仿Go语言的Benchmark测试框架写了JAVA版的简化测试工具
- Go语言学习笔记--类型、指针、面向对象
- Go语言学习之cgo(golang与C语言相互调用)
- Go语言中调用C语言----类型转换篇
- Go语言的9大优势和3大缺点, GO语言最初的定位就是互联网时代的C语言, 我为什么放弃Go语言
- C语言面向对象的程序设计语言
- go语言面向对象
- go语言之面向对象一
- go语言接收c语言消息中文乱码问题
- Go语言中嵌入C语言的方法
- 面向过程(C语言)和面向对象(OC语言)
- go语言和C语言的对比
- C语言和go语言之间的交互 - C语言中使用go语言,使用的go语言又使用了c语言
- GO语言中的面向对象与接口
- Go语言中面向对象-结构体和方法
- Go语言最佳实践——面向对象
- go语言和C语言的对比
- 俺使用的C语言面向对象范式(前言与第一节:一个简单类的封装)
- Go语言中面向对象-包和封装的使用
- Go语言的编程范式