C 语言部分实现面向对象的继承特性
来源:互联网 发布:淘宝福利秀 编辑:程序博客网 时间:2024/05/16 14:31
最近在研究Linux源码的时候遇到很多不曾见过的C语言用法,尤其是一些面相对象的特性。最熟悉的是C99标准,最新的C11标准没有仔细研究过,泛泛看了一下资料觉得也主要是增加了一些对多线程支持的特性,对于面向对象的特性应该没有。
搜索了一下,找到一篇很好的文章。该文章采用C语言很灵巧的实现了部分面向对象的继承特性。
遗憾的是源代码貌似有问题,对于struct的内存布局有问题,同时也编译不过,因此我修改了一下,随后也会和原文作者一起讨论和分析。
感兴趣的同学,请先移步到本文的参考文章看下:
http://www.cnblogs.com/haippy/archive/2012/12/31/2840501.html
因为我对代码进行了不少改动,包括基类的设计实现、封装性方面,因此文章属性定为原创,这里先向原作者表示歉意和感谢。
下面是我修改的代码,在VS2008和gcc中编译过的,可以正常运行。VS2008中仅支持C89的编译标准,因此如果写C代码最好是用gcc编译。
//animal_base.h:
#ifndef _ANIMAL_H_
#define _ANIMAL_H_
typedef struct animal_s_ animal_t;
typedef struct animal_ops_s_ animal_ops_t;
/* 动物的基本行为 */
struct animal_ops_s_ {
void (*eat)(char *food);
void (*walk)(int steps);
void (*talk)(char *msg);
};
/* 动物类,是所有动物类的基类,也是抽象类 */
struct animal_s_ {
animal_ops_t animal_ops; /* 动物的基本行为 */
};
/* 基类的构造函数,需要显示调用 */
animal_t * animal_init();
/* 基类的有关操作,如吃,走,说等等 */
void animal_eat(animal_t *animal, char *food);
void animal_walk(animal_t *animal, int steps);
void animal_talk(animal_t *animal, char *msg);
/* 基类的析构函数,需要显示调用 */
void animal_die(animal_t *animal);
#endif /* _ANIMAL_H_ */
//animal_base.c
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "animal_base.h"
/* 基类的构造函数,需要显示调用 */
animal_t * animal_init()
{
animal_t *animal = (animal_t *)malloc(sizeof(animal_ops_t));
memset(animal, 0, sizeof(animal_ops_t));
return animal;
}
/* 基类的有关操作,如吃,走,说等等 */
void animal_eat(animal_t *animal, char *food)
{
animal->animal_ops.eat(food);
}
void animal_walk(animal_t *animal, int steps)
{
animal->animal_ops.walk(steps);
}
void animal_talk(animal_t *animal, char *msg)
{
animal->animal_ops.talk(msg);
}
/* 基类的析构函数,需要显示调用 */
void animal_die(animal_t *animal)
{
assert(animal != NULL);
free(animal);
}
//cat.h
#include "animal_base.h"
typedef struct cat_s_ cat_t;
struct cat_s_ {
animal_t base; /*animal基类数据成员必须位于第一个成员声明的位置 */
/* 以下还可以添加与 cat 相关的属性和方法(函数指针), 如: */
/* char *owner; // cat 的主人 */
/* void (*hunt)(const char *rabbit); // 猎兔犬 */
};
cat_t * cat_init();
void cat_die(cat_t * cat);
//cat.c
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "cat.h"
static void eat(char *food);
static void walk(int steps);
static void talk(char *msg);
cat_t * cat_init()
{
cat_t *cat = (cat_t *)malloc(sizeof(cat_t));
animal_t *animal = (animal_t *)animal_init();
memcpy(&(cat->base), animal, sizeof(animal_t));
cat->base.animal_ops.eat = eat;
cat->base.animal_ops.walk = walk;
cat->base.animal_ops.talk = talk;
animal_die(animal);
return cat;
}
void cat_die(cat_t *cat)
{
assert(cat != NULL);
free(cat);
}
static void eat(char *food)
{
printf("I'm a cat, I eat %s\n", food);
}
static void walk(int steps)
{
printf("I'm a cat, I can jump %d steps one time\n", steps);
}
static void talk(char *msg)
{
printf("I'm a cat, I talk my language %s\n", msg);
}
//dog.h
#include "animal_base.h"
typedef struct dog_s_ dog_t;
struct dog_s_ {
animal_t base; /* animal基类数据成员必须位于第一个成员声明的位置*/
/* 以下还可以添加与 dog 相关的属性和方法(函数指针), 如: */
/* char *owner; // dog 的主人 */
/* void (*hunt)(const char *rabbit); // 猎兔犬 */
};
dog_t * dog_init();
void dog_die(dog_t * dog);
//dog.c
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "dog.h"
static void eat(char *food);
static void walk(int steps);
static void talk(char *msg);
dog_t * dog_init()
{
dog_t *dog = (dog_t *)malloc(sizeof(dog_t));
animal_t *animal = (animal_t *)animal_init();
memcpy(dog, animal, sizeof(animal_t));
dog->base.animal_ops.eat = eat;
dog->base.animal_ops.walk = walk;
dog->base.animal_ops.talk = talk;
animal_die(animal);
return dog;
}
void dog_die(dog_t *dog)
{
assert(dog != NULL);
free(dog);
}
static void eat(char *food)
{
printf("I'm a dog, I eat %s\n", food);
}
static void walk(int steps)
{
printf("I'm a dog, I can jump %d steps one time\n", steps);
}
static void talk(char *msg)
{
printf("I'm a dog, I talk my language %s\n", msg);
}
//main.c
#include <stdio.h>
#include "animal_base.h"
#include "dog.h"
#include "cat.h"
int main(int argc, const char *argv[])
{
dog_t *dog = dog_init();
cat_t *cat = cat_init();
/* dog 类测试 */
animal_eat((animal_t *)dog, "bones");
animal_walk((animal_t *)dog, 5);
animal_talk((animal_t *)dog, "wuang wuang wuang...");
/* cat 类测试 */
animal_eat((animal_t *)cat, "fish");
animal_walk((animal_t *)cat, 3);
animal_talk((animal_t *)cat, "miao miao miao...");
dog_die(dog);
cat_die(cat);
getchar();
}
运行结果:
(完)
题后: 本文中实际上是有商榷的地方的,请移步重构后的版本。
0 0
- C 语言部分实现面向对象的继承特性
- C 语言部分实现面向对象的继承特性【重构】
- C语言面向对象的实现---继承性
- C语言面向对象的实现---继承性
- C语言面向对象的实现---继承性
- C语言实现C++面向对象语言多态特性
- 面向对象的特性:继承
- C++面向对象语言的重要特性之一 继承
- C++面向对象语言的重要特性之一 继承 .
- C 语言面向对象-- 继承
- C实现面向对象的继承
- 面向对象语言特性之继承
- C语言实现C++中面向对象特性
- C语言实现面向对象之继承性
- 面向对象之继承,封装,多态c语言实现
- C语言实现面向对象之继承性
- c语言实现面向对象之继承,多态
- C语言实现面向对象的思想(实现封装、继承和多态)
- Valid Parentheses
- Android 计算控件尺寸
- android图片处理方法(不断收集中)
- 两幅图像的线性叠加
- LeetCode-Median of Two Sorted Arrays
- C 语言部分实现面向对象的继承特性
- 文件编码转换工具类
- 若干关于 字符串 的小算法
- Linux进程后台运行 nohup
- 黑马程序员 【】java学习之路——GUI开始简析
- C++标准库string类型
- Unity Mathf 数学运算(C#)
- openwrt DTSI文件解译
- iframe自适应高度加载脚本,解决不能使用onload事件问题(兼容)