2009-04-23 16:56
#include <stdio.h>
#include <stdlib.h>
#define GET_VTBL(p,type) ((type*)(void*)p)->vt //p必须有vt成员
typedef struct _IBase IBase; //方便使用
typedef struct _Base Base;
struct _IBase
{
void (*Show)(IBase *p); //函数指针
};
struct _Base
{
IBase vt; //相当于虚函数表
};
void Base_Show(IBase *p) //函数定义
{
printf("This is Base_Show()\n");
}
void InitBase(Base **p) //初始化
{
*p = (Base*)malloc(sizeof(Base));
(*p)->vt.Show = Base_Show;
}
#define IBASE_Show(p) GET_VTBL(p,Base).Show((IBase*)p); //方便使用
typedef struct _IInherit IInherit; //派生类
typedef struct _Inherit Inherit;
struct _IInherit
{
void (*Show)(IBase *p); //注意:名称和顺序与基类相同
void (*Show2)(IInherit *p); //派生函数
};
struct _Inherit
{
IInherit vt;
int data;
};
void Inherit_Show(IBase *p) //派生类函数,改写基类函数
{
printf("This is Inherit_Show(), data=%d\n", ((Inherit*)p)->data);
}
void Inherit_Show2(IInherit *p) //派生类扩展函数
{
printf("This is Inherit_Show2(), data=%d\n", ((Inherit*)p)->data);
}
void InitInherit(Inherit **p) //初始化
{
*p = (Inherit*)malloc(sizeof(Inherit));
(*p)->vt.Show = Inherit_Show;
(*p)->vt.Show2 = Inherit_Show2;
(*p)->data = 10;
}
#define IINHERIT_Show(p) GET_VTBL(p,Inherit).Show((IInherit*)p); //方便使用
#define IINHERIT_Show2(p) GET_VTBL(p,Inherit).Show2((IInherit*)p);
void main()
{
Base *p = 0;
InitBase(&p); //初始化基类指针
IBASE_Show(p);
free(p);
InitInherit((Inherit **)&p); //初始化派生类指针
IBASE_Show(p); //以派生类实例调用基类接口,多态的关键
IINHERIT_Show2((Inherit *)p); //调用派生类接口
free(p);
getchar(); //停一下,看看输出结果吧
}
/*
输出结果如下:
This is Base_Show()
This is Inherit_Show(), data=10 //这一步,是多态的关键
This is Inherit_Show2(), data=10
总结:
1、如果结构体的成员是结构体,相当于成员结构体展开在新的结构体中,参数的顺序结构不变,这个是基础的基础。
2、使用函数指针调用函数,可以在运行时指向不同的函数,这个是多态的关键。(貌似这里并没有用到)
*/