最近在研究Linux源码的时候遇到很多不曾见过的C语言用法,尤其是一些面相对象的特性。最熟悉的是C99标准,最新的C11标准没有仔细研究过,泛泛看了一下资料觉得也主要是增加了一些对多线程支持的特性,对于面向对象的特性应该没有。
//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
#include
#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
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
#include
#include
#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
#include
#include
#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 "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();
}
运行结果: