c/c++语言开发共享C语言实现C++多态——函数指针

序: 前段时间,去复试淘米的面试,被问到了怎么用c语言实现c++中的多态,当时,只是模模糊糊的知道,使用函数指针可以达到c++多态的效果,但是,具体怎么实现,却还是不清楚。最终面试官让我说了一下c+

序:
前段时间,去复试淘米的面试,被问到了怎么用c语言实现c++中的多态,当时,只是模模糊糊的知道,使用函数指针可以达到c++多态的效果,但是,具体怎么实现,却还是不清楚。最终面试官让我说了一下c++中的多态。虽然知道被挂在了二面,但是,却感觉并没有什么,每一次的失败,都是为了最后一次的成功积蓄力量,回报越晚,回报越大。这不,因为这件事情,我知道了怎么用c语言实现c++的多态。
正文:
1.首先,弄清楚一个问题,c++多态。
(注:摘自c和c++程序员面试秘笈)
多态:同一操作作用于不同对象,可以有不同的解释,产生不同的执行结果。有两种类型的多态性:
<1>编译时的多态性:编译时的多态性是通过重载函数来实现的。对于非虚的成员函数来说,在编译时,根据传递的参数、返回的类型等信息决定实现何种操作。
<2>运行时的多态性:运行时的多态性就是指直到系统运行时,才根据实际情况决定实现何种操作。c++中,运行时的多态性通过虚成员实现。
示例:

  这里写代码片      #include       using namespace std;          class a      {      public:          virtual void f()          {              cout << "a::f()" << endl;          }      };          class b:public a      {      public:          virtual void f()          {              cout << "b::f()" << endl;          }      };          class c:public b      {      public:          void f()          {              cout << "c::f()" << endl;          }      };          void test(a &a)         //基类的指针或引用      {             a.f();              //运行时多态      }          int main()      {          a a;          b b;          c c;          test(a);          test(b);          test(c);          return 0;      }

c/c++语言开发共享C语言实现C++多态------函数指针
2.c语言实现c++中的多态

  这里写代码片    <1>基类头文件    #ifndef _animal_h_    #define _animal_h_    //动物的行为    typedef struct animal_ops_s_    {    void (*eat)(char *food); //吃什么食物    void (*walk)(int steps); //走多少步    void (*talk)(char *msg); //说什么    }animal_ops_t;    //动物类,所有动物的基类(抽象类)    typedef struct animal_s_    {    char *name; //动物的名称    animal_ops_t *animal_ops; //动物的行为    }animal_t;    //基类的构造函数,需要显示调用    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    <1>基类的实现    #include    #include    #include    #include "animal.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));    memset(animal,0,sizeof(animal));    animal->name = (char *)malloc(name_len + 1);    memcpy(animal->name,name,name_len+1);    animal->animal_ops = (animal_ops_t *)((char *)animal+name_len + 1);    animal->animal_ops->eat = null;    animal->animal_ops->walk = null;    animal->animal_ops->talk = null;    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)    {    return ;    }    <2>汪星人头文件    #ifndef _dog_h_    #define _dog_h_    #include "animal.h"    typedef struct dog_s_ dog_t;    struct dog_s_    {    animal_t base; //继承自animal基类    };    extern dog_t *dog_init();    extern void dog_die(dog_t *dog);    #endif    <2>汪星人实现    #include    #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("hello-dog");    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;    animal_die(animal);    return dog;    }    void dog_die(dog_t *dog)    {    assert(dog != null);    free(dog);    dog = null;    }    static void eat(char *food)    {    printf("i'm a dog,i eat %sn",food);    }    static void walk(int steps)    {    printf("i'm a dog, i can jump %d stepsn",steps);    }    static void talk(char *msg)    {    printf("i'm a dog,i talk my language %sn",msg);    }    <3>喵星人头文件    #ifndef _cat_h_    #define _cat_h_    #include "animal.h"    typedef struct cat_s_ cat_t;    struct cat_s_    {    animal_t base; //继承自animal基类    };    extern cat_t *cat_init();    extern void cat_die(cat_t *cat);    #endif    <3>喵星人实现    #include    #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("hello-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;    return cat;    }    void cat_die(cat_t *cat)    {    assert(cat != null);    free(cat);    cat = null;    }    static void eat(char *food)    {    printf("i'm a cat,i eat %sn",food);    }    static void walk(int steps)    {    printf("i'm a cat,i can jump %d stepsn",steps);    }    static void talk(char *msg)    {    printf("i'm a cat,i talk my language %sn",msg);    }    <4>主函数    #include    #include "animal.h"    #include "dog.h"    #include "cat.h"    int main()    {    cat_t *cat = cat_init();    dog_t *dog = dog_init();    //dog测试    animal_eat(dog,"bones");    animal_walk(dog,5);    animal_talk(dog,"wang wang wang...");    //cat测试    animal_eat(cat,"fish");    animal_walk(cat,3);    animal_talk(cat,"miao miao miao...");    cat_die(cat);    dog_die(dog);    return 0;  

 

<5>程序运行结果截图:
C语言实现C++多态------函数指针
3.感悟
实际上,在c语言中,模仿c++实现多态的过程中,对于构造和析构函数都是要显示的进行调用,对于类的成员函数,实际上是通过结构体内部封装的函数指针完成的。而对于从基类继承而来的派生类,它的虚表的确定,实际上是在自身的构造函数中显示的调用基类的构造函数,然后复制基类的构造函数的内容,之后,可以在自己的类中添加一些其他的操作,而对于自己本身的函数成员,在本模块内有效,声明为静态函数,这样就可以避免命名的冲突问题。总之,在c语言中要想实现多态,函数指针是唯一法宝。

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/c-cdevelopment/607988.html

(0)
上一篇 2021年5月14日
下一篇 2021年5月14日

精彩推荐