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\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);

}
复制代码

喵星人(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\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);

}
复制代码

最后,测试代码如下:

复制代码
/*

 * =============================================================================

 *

 *       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...
复制代码

你可能感兴趣的:(C语言)