首页
社区
课程
招聘
[原创]C语言学习总结之如何实现继承和函数重写
发表于: 2012-11-11 02:28 7857

[原创]C语言学习总结之如何实现继承和函数重写

2012-11-11 02:28
7857
/*==============hero.c=====================*/
/*这是一个C语言实现继承和重写方法的例子
*继承的实现很简单,只要在子类的结构全里包含父类结构体的成员即可
*函数重写则是通过函数指针实现的,父类和子类在初始化进都把自己相应的函数赋值给一个函数指针,
*调用函数时我们都调用这个函数指针,这样就实现了重写,所以,所谓重写,就是给一个函数指针赋值的过程
*/
#include "string.h"
#include <stdio.h>

typedef enum
{
        POWER,//力量型英雄
        AGILITY,//敏捷型英雄
        WISDOM//智力型英雄
}HeroType;

#define HERO_MEMBER\
        int* virtual_table;/*虚表的指针,这就是传说中的虚表*/\
        char name[32];/*英雄名称*/\
        HeroType type;/*英雄类型*/\
        int level;/*等级*/\
        int blood;/*血量*/\
        int attack;/*攻击力*/\
       

typedef struct
{
        HERO_MEMBER//定义成员变量,把成员变量声明为一个宏,主要是为了方便继承
}Hero;//所有英雄的父类

//下面是hero的成员方法,this在C语言中不是关键字,所以我们可以用this做为形参的名称
void HeroInit(Hero* this,char *name,HeroType type,int level,int blood,int attack);
void HeroIntroduceDefault(Hero *this);

//虚函数调用
typedef void (*HeroIntroduceFun)(Hero *this);//函数指针
#define HeroIntroduce(pHero) ((HeroIntroduceFun)(pHero->virtual_table[0]))(pHero);//调用虚函数,从虚表中取得函数地址,强制转换成相应的函数指针,再调用

int HERO_VIRTUAL_TABLE[]={(int)HeroIntroduceDefault};//HERO的虚表,只有一个虚函数,把所有的虚函数集合在一个表是为了省内存

//初始化,类似于构靠函数
void HeroInit(Hero* this,char *name,HeroType type,int level,int blood,int attack)
{
        this->virtual_table=HERO_VIRTUAL_TABLE;//这句是重点
        strcpy(this->name,name);
        this->type=type;
        this->level=level;
        this->blood=blood;
        this->attack=attack;
}

//默认的介绍自己的方法
void HeroIntroduceDefault(Hero *this)
{
        char *type_str[]={"力量","敏捷","智力"};
        printf("我是%s,我的基本信息是:\n",this->name);
        printf("类型:\t%s\n",type_str[this->type]);
        printf("等级:\t%d\n",this->level);
        printf("血量:\t%d\n",this->blood);
        printf("攻击力:\t%d\n",this->attack);
}

typedef struct
{
        HERO_MEMBER/*斧王继承于Hero,所以要包含Hero的成员变量*/\
        int helic;/*斧王反击螺旋的等级*/
}FuWang;//斧王
//正面是斧王的成员方法
void FuWangInit(FuWang *this,int helic);
void FuWangIntroduce(FuWang *this);

void FuWangInit(FuWang *this,int helic)
{
        HeroInit((Hero*)this,"斧王",POWER,1,450,100);//调用父类的构造方法,初始化自己
        this->helic=helic;
        this->virtual_table[0]=(int)FuWangIntroduce;//这个是重点,这样就实现了重写
}

void FuWangIntroduce(FuWang *this)
{
        HeroIntroduceDefault((Hero*)this);//先调用父类的方法
        printf("除此之外,我在被攻击的时候我能自动用螺旋进行反击:\n");
        printf("反击螺旋等级:\t%d\n",this->helic);
}

typedef struct
{
        HERO_MEMBER/*蓝胖子继承于Hero,所以要包含Hero的成员变量*/\
        int explode;/*蓝胖子反击螺旋的等级*/
}LanPangZi;//蓝胖子

//正面是蓝胖子的成员方法
void LanPangZiInit(LanPangZi *this,int helic);
void LanPangZiIntroduce(LanPangZi *this);

void LanPangZiInit(LanPangZi *this,int explode)
{
        HeroInit((Hero*)this,"蓝胖子",WISDOM,2,400,90);//调用父类的构造方法,初始化自己
        this->explode=explode;
        this->virtual_table[0]=(int)LanPangZiIntroduce;//这个是重点,这样就实现了重写
}

void LanPangZiIntroduce(LanPangZi *this)
{
        HeroIntroduceDefault((Hero*)this);//先调用父类的方法
        printf("除此之外,我能爆人:\n");
        printf("爆人等级:\t%d\n",this->explode);
}

int main(int argv,char*argc[])
{
        FuWang fw;
        LanPangZi lpz;
        Hero *hero;

        FuWangInit(&fw,1);//调用斧王构造函数,初始化斧王
        LanPangZiInit(&lpz,2);//调用蓝胖子构造函数,初始化蓝胖子

        hero=(Hero*)&fw;//父类指针引用子类对象
        HeroIntroduce(hero);//神奇的多态要发生了

        printf("\n");

        hero=(Hero*)&lpz;//父类指针引用子类对象
        HeroIntroduce(hero);//神奇的多态又发生了
       
        getchar();
}

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 0
支持
分享
最新回复 (11)
雪    币: 31
活跃值: (48)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
2
嗯,不错,还差了多态呢。这些只是实现它们,和C++等的支持它们还是有很大区别的。
2012-11-11 09:55
0
雪    币: 62
活跃值: (101)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
楼主莫非是纯秀代码来着?

搞DOTA外挂么?
2012-11-12 19:20
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
看看吧,前排支持楼主
2012-11-12 20:07
0
雪    币: 1233
活跃值: (907)
能力值: ( LV12,RANK:750 )
在线值:
发帖
回帖
粉丝
5
莫名其妙,c语言就用c语言啊,学什么c++啊?
2012-11-12 20:43
0
雪    币: 17
活跃值: (25)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
6
解释原理,通过用C语言来解释面向对象实现的方法。
再说这种写法在C语言真实项目中也并不少见。
我只是想说明C语言的强大,所有的东西都来自于C。
2012-11-14 16:26
0
雪    币: 17
活跃值: (25)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
7
不好意思,不会搞外挂
2012-11-14 16:27
0
雪    币: 1358
活跃值: (17)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
学习了,谢谢共享!
2012-11-16 16:58
0
雪    币: 132
活跃值: (214)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
9
还是很有价值的!支持楼主!至于5楼的回复楼主大可不必理睬。。。应该把帖子标题改为;C实现继承跟多态就有吸引力了。
2012-11-18 12:48
0
雪    币: 278
活跃值: (709)
能力值: ( LV15,RANK:520 )
在线值:
发帖
回帖
粉丝
10
有意思吗?感情问一句:C为什么不叫C++呢?用C实现不是多此一举吗?
2012-11-18 19:30
0
雪    币: 132
活跃值: (214)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
11
为什么是多此一举?模拟可以理解的更加深刻有木有啊!有些人只是追求应用层表面层的,比如MFC吧,很多人都晓得拖拖控件再CLICK几下就好了,但人家深入浅出MFC不也是大卖吗?说明还是有很多人是不满足表面的,喜欢钻研问题的。我们不能把自己的思想强加给别人,认为我们不需要去用C模拟C++别人也不需要,大道理其实都懂的,我不是替楼主说话,只是认为有些人无意中会“伤害”到象楼主这样的人,从而打击了别人学习的积极性。。。任何人都有喜欢与讨厌的自由,比较好的做法是:喜欢的可以留言鼓励人家,不喜欢的绕道就行了,不需要留下那些没必要的“废话”。。。。。。
2012-11-18 22:47
0
雪    币: 278
活跃值: (709)
能力值: ( LV15,RANK:520 )
在线值:
发帖
回帖
粉丝
12
谢谢指教,记住了。
2012-11-19 15:01
0
游客
登录 | 注册 方可回帖
返回
//