实现C语言的继承和多态

较经典的动物世界中的实例来举例:
假设动物们(包括人)都会吃(Eat),会走(Walk),会说(Talk),而派生类为 dog(汪星人) 和 cat(喵星人),当然还可以是更多,dog 和 cat 都有自己独特的 eat, walk 和 talk 方式,那么大致的代码如下:
代码无警告编译运行

基类头文件

// animal.h
#ifndef ANIMAL_H__
#define ANIMAL_H__

typedef struct animal_s_ animal_t;
typedef struct animal_ops_s_ animal_ops_t;

struct animal_s_ {
        char *name;
        animal_ops_t *animal_ops;
};

struct animal_ops_s_ {
        void (*eat)(char *);
        void (*walk)(int);
        void (*talk)(char *);
};

animal_t *animal_init(char *name);

void animal_eat(animal_t *, char *food);
void animal_walk(animal_t *, int steps);
void animal_talk(animal_t *, char *msg);

void animal_die(animal_t *);

#endif//ANIMAL_H__

基类实现

// animal.c
#include <assert.h>
#include <stdlib.h>
#include <string.h>

#include "animal.h"

animal_t *animal_init(char *name)
{
        assert(name != NULL);
        size_t name_len = strlen(name);

        animal_t *animal = malloc(sizeof (*animal)
                + sizeof (animal_ops_t) + name_len + 1);
        memset(animal, 0, sizeof (*animal)
                + sizeof (animal_ops_t) + name_len + 1);
        animal->name = (char *)animal
                + sizeof (animal_t) + sizeof (animal_ops_t);
        memcpy(animal->name, name, name_len);
        animal->animal_ops = (animal_ops_t *)((char *)animal
                + sizeof (*animal));

        return animal;
}

void animal_eat(animal_t *animal, char *food)
{
        animal->animal_ops->eat(food);

        return;
}

void animal_walk(animal_t *animal, int steps)
{
        animal->animal_ops->walk(steps);

        return;
}

void animal_talk(animal_t *animal, char *msg)
{
        animal->animal_ops->talk(msg);

        return;
}

void animal_die(animal_t *animal)
{
        assert(animal != NULL);
        free(animal);

        return;
}

子类cat头文件

// cat.h
#ifndef CAT_H__
#define CAT_H__

#include "animal.h"

typedef struct cat_s_ cat_t;

struct cat_s_ {
        animal_t base;
        // char *owner;
        // void (*hunt)(const char *mouse);
};

cat_t *cat_init(void);
void cat_die(cat_t *);

#endif//CAT_H__

实现cat函数

// cat.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

#include "cat.h"

static void eat(char *food);
static void walk(int steps);
static void talk(char *msg);

cat_t *cat_init(void)
{
        cat_t *cat = malloc(sizeof (*cat));
        animal_t *animal = (animal_t *)animal_init("cat");
        memcpy(&(cat->base), animal, sizeof (*animal));

        cat->base.animal_ops->eat = eat;
        cat->base.animal_ops->walk = walk;
        cat->base.animal_ops->talk = talk;

        free(animal);

        return cat;
}

void cat_die(cat_t *cat)
{
        // nothing to here.
}

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类头文件

// dog.h
#ifndef DOG_H__
#define DOG_H__
#include "animal.h"

typedef struct dog_s_ dog_t;

struct dog_s_ {
        animal_t base;
        // char *owner;
        // void (*hunt)(const char *rabbit);
};

dog_t *dog_init(void);
void dog_die(dog_t *);

#endif//DOG_H__

dog类实现函数

// dog.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

#include "dog.h"

static void eat(char *food);
static void walk(int steps);
static void talk(char *msg);

dog_t *dog_init(void)
{
        dog_t *dog = malloc(sizeof (*dog));
        animal_t *animal = (animal_t *)animal_init("dog");
        memcpy(&(dog->base), animal, sizeof (*animal));

        dog->base.animal_ops->eat = eat;
        dog->base.animal_ops->walk = walk;
        dog->base.animal_ops->talk = talk;

        free(animal);

        return dog;
}

void dog_die(dog_t *dog)
{
        // nothing to do here.
}

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.h"
#include "dog.h"
#include "cat.h"

int main(int argc, const char *argv[])
{
        dog_t *dog = dog_init();
        cat_t *cat = cat_init();

        animal_eat((animal_t *)dog, "bones");
        animal_walk((animal_t *)dog, 5);
        animal_talk((animal_t *)dog, "wang wang wang...");

        animal_eat((animal_t *)cat, "fish");
        animal_walk((animal_t *)cat, 3);
        animal_talk((animal_t *)cat, "miao miao miao...");

        return 0;
}

可以有的makefile文件

# makefile
all:    main
main:   main.o dog.o cat.o animal.o
        $(CC) -Wall -W -o $@ $^
main.o:         main.c
animal.o:       animal.c
dog.o:          dog.c
cat.o:          cat.c

.PHONY: clean

clean:
        rm -rf *.o main

linux下编译运行

[lhf@localhost animal]$ ls
animal.c  animal.h  cat.c  cat.h  dog.c  dog.h  main.c  makefile
[lhf@localhost animal]$ make
cc    -c -o main.o main.c
cc    -c -o dog.o dog.c
cc    -c -o cat.o cat.c
cc    -c -o animal.o animal.c
cc -Wall -W -o main main.o dog.o cat.o animal.o
[lhf@localhost animal]$ ./main
I'm a cat, I eat bones.
I'm a cat, I can jump 5 steps one time.
I'm a cat, I talk my language wang wang wang....
I'm a cat, I eat fish.
I'm a cat, I can jump 3 steps one time.
I'm a cat, I talk my language miao miao miao....

参考 http://www.cnblogs.com/haippy/archive/2012/12/31/2840501.html

发表评论

电子邮件地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据