zoukankan      html  css  js  c++  java
  • c语言中继承和多态的简单实现

      C语言本身是不支持继承和多态的,但其实在 C 的世界里,有一套非常有名的面向对象的框架,用的也非常广,那就是 GObject,它是整个图形界面开发库 GTK 的基石,在IBM developerWorks上有一篇很好的文章介绍 GObject《GObject对象系统》。另外,在 Linux 内核里面也大量使用了面向对象的思想,比如虚拟文件系统,设备驱动等模块,在 lwn 上有两篇文章就讲到了内核中的面向对象,详细请看:《Object oriented design patterns in the kernel, part 1》,《Object oriented design patterns in the kernel, part 2》。

      c语言里继承和多态的实现主要通过函数指针来实现,现在我们就来动手实现C语言的继承与多态,我们以比较经典的动物世界中的实例来举例:假设动物们(包括人)都会吃(Eat),会走(Walk),会说(Talk),而派生类为 dog(汪星人) 和 cat(喵星人),当然还可以是更多,dog 和 cat 都有自己独特的 eat, walk 和 talk 方式,那么大致的代码如下:

    基类代码 animal-base.h|c:

    /*
     * =============================================================================
     *
     *       Filename:  animal-base.h
     *
     *    Description:  animal base class.
     *      
     *
     * =============================================================================
     */
    #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 *food);
        /* 动物走了多少步 */
        void (*walk)(int steps);
        /* 动物在说什么 */
        void (*talk)(char *msg);
    };
    
    /* 基类的构造函数,需要显示调用 */
    extern animal_t * animal_init(char *name);
    
    /* 基类的有关操作,如吃,走,说等等 */
    extern void animal_eat(animal_t *animal, char *food);
    extern void animal_walk(animal_t *animal, int steps);
    extern void animal_talk(animal_t *animal, char *msg);
    
    /* 基类的析构函数,需要显示调用 */
    extern void animal_die(animal_t *animal);
    
    #endif  /* _ANIMAL_H_ */
    复制代码
    复制代码
    /*
     * =============================================================================
     *
     *       Filename:  animal-base.c
     *
     *    Description:  animal base class.
     *
     * =============================================================================
     */
    #include <assert.h>
    #include <stdlib.h>
    #include <string.h>
    
    #include "animal-base.h"
    
    /* 基类的构造函数,需要显示调用 */
    animal_t * animal_init(char *name)
    {
        assert(name != NULL);
        size_t name_len = strlen(name);
    
        animal_t *animal = (animal_t *)malloc(sizeof(animal_t)
                + sizeof(animal_ops_t) + name_len + 1);
        memset(animal, 0, (sizeof(animal_t) + sizeof(animal_ops_t)
                    + name_len + 1));
        animal->name = (char *)animal + sizeof(animal_t);
        memcpy(animal, name, name_len);
        animal->animal_ops = (animal_ops_t *)((char *)animal
                + sizeof(animal_t) + name_len + 1);
    
        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;
    }
    复制代码

    汪星人 dog 类的实现代码:

    复制代码
    #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); // 猎兔犬 */
    };
    
    extern dog_t * dog_init();
    extern void dog_die(dog_t * dog);
    复制代码
    复制代码
    /*
     * =============================================================================
     *
     *       Filename:  dog.c
     *
     *    Description:  dog class derived from animal base class.
     *
     * =============================================================================
     */
    #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("doggggggggggggg");
        memcpy(&(dog->base), animal, sizeof(animal_t));
    
        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
    ", food);
    }
    
    static void walk(int steps)
    {
        printf("I'm a dog, I can jump %d steps one time
    ", steps);
    }
    
    static void talk(char *msg)
    {
        printf("I'm a dog, I talk my language %s
    ", msg);
    }
    复制代码

    喵星人(cat 类) 的实现代码:

    复制代码
    /*
     * =============================================================================
     *
     *       Filename:  cat.h
     *
     *    Description:  cat class derived from animal base class.
     *
     * =============================================================================
     */
    #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); // 猎兔犬 */
    };
    
    extern cat_t * cat_init();
    extern void cat_die(cat_t * cat);
    复制代码
    复制代码
    /*
     * =============================================================================
     *
     *       Filename:  cat.c
     *
     *    Description:  cat class derived from animal base class.
     * =============================================================================
     */
    #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("cat");
        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;
    
        free(animal);
        return cat;
    }
    
    void cat_die(cat_t *cat)
    {
        /* nothing to do here. */
    }
    
    static void eat(char *food)
    {
        printf("I'm a cat, I eat %s
    ", food);
    }
    
    static void walk(int steps)
    {
        printf("I'm a cat, I can jump %d steps one time
    ", steps);
    }
    
    static void talk(char *msg)
    {
        printf("I'm a cat, I talk my language %s
    ", msg);
    }
    复制代码

    最后,测试代码如下:

    复制代码
    /*
     * =============================================================================
     *
     *       Filename:  main.c
     *
     *    Description:  main test.
     *
     *
     * =============================================================================
     */
    #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(dog, "bones");
        animal_walk(dog, 5);
        animal_talk(dog, "wuang wuang wuang...");
    
        /* cat 类测试 */
        animal_eat(cat, "fish");
        animal_walk(cat, 3);
        animal_talk(cat, "miao miao miao...");
    
    }
    复制代码

    还有Makefile :

    复制代码
    all:main
    
    main:main.o dog.o cat.o animal-base.o
        gcc -o $@ $^
    
    main.o:main.c
    
    cat.o:cat.c
    
    dog.o:dog.c
    
    animal-base.o:animal-base.c
    
    .PHONY:clean
    
    clean:
        rm main main.o dog.o cat.o animal-base.o
    复制代码

    最后执行结果为:

    复制代码
    I'm a dog, I eat bones
    I'm a dog, I can jump 5 steps one time
    I'm a dog, I talk my language wuang wuang wuang...
    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...
    复制代码
  • 相关阅读:
    USACO 5.5 Twofive
    USACO 5.4 Telecowmunication
    USACO 5.4 Character Recognition
    BZOJ 1001: [BeiJing2006]狼抓兔子
    USACO 5.4 Canada Tour
    USACO 5.3 Big Barn
    USACO 5.3 Network of Schools
    USACO 5.3 Window Area
    2017辽宁冬令营-4.蚂蚁
    2017辽宁冬令营-3.斐波那契
  • 原文地址:https://www.cnblogs.com/lippi/p/3759900.html
Copyright © 2011-2022 走看看