C语言实现多态
C语言实现多态
首先声明,大神就不要看了。小弟水平有限。
C++多态是通过虚函数表实现的,类似于JAVA多态的实现方式。关于Java多态的实现方式可以看我之前写过的一篇不是很完善的文章。从JVM角度看Java多态。
Java和C++不同,Java中所有的实例方法(相对于类方法,或叫静态方法而言)都是默认为虚函数,之前貌似看到过Java生成的字节码中,所有实例方法前面都是右virtual关键字的。C++中需要显示声明virtual之后才是虚函数,虚函数是实现多态的基础。
今天用C语言实现的多态,是实现一个类似下面的C++代码:(由于使用QtCreator写的,所以会有一点儿QT的代码,可以忽略)
#include <QCoreApplication> #include <iostream> using namespace std; class Base{ public: virtual void eat(){ cout<<"基类在吃饭....."<<endl; } virtual void play(){ cout<<"基类在玩耍....."<<endl; } }; class DeriveA:public Base{ public: void eat(){ cout<<"子类A在吃饭....."<<endl; } }; class DeriveB:public Base{ public: void eat(){ cout<<"子类B在吃饭....."<<endl; } }; int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); Base * base; DeriveA dA; DeriveB dB; base = &dA; base->eat(); base->play(); cout<<"---------------------------------------------\n"; base = &dB; base->eat(); base->play(); return a.exec(); }
其中,基类中有两个虚函数,eat()和play(),两个派生类中都只重写了基类的eat()方法。
输出结果如下图:
下面用纯C语言实现类似的效果。可以用C语言模仿C++的虚函数表。
首先定义两个函数指针类型:
typedef void (*EatPtr)(); typedef void (*PlayPtr)();
接着模拟虚函数表,虚函数表就是一个元素为虚函数指针的结构体
typedef struct _virtualPtrTable{ EatPtr eat; PlayPtr play; }VPtrTable;
接着定义“基类和派生类”:
typedef struct _base{ VPtrTable vptrTable; int age; }Base; typedef struct _deriveA{ Base base; int age; }DeriveA; typedef struct _deriveB{ Base base; int age; }DeriveB;
接着实现函数,由于C++代码中,两个派生类都没有实现play方法,所以这里派生类的play函数都只是调用基类的函数。。
/** 派生类A的实现函数 **/ void aEat(){ cout<<"子类A在吃饭....."<<endl; } void aPlay(){ basePlay(); } /** 派生类B的实现函数 **/ void bEat(){ cout<<"子类B在吃饭....."<<endl; } void bPlay(){ basePlay(); }
下面是主函数:
int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); Base *base; DeriveA deriveA; deriveA.base.vptrTable.eat = aEat; deriveA.base.vptrTable.play = aPlay; deriveA.base.age = 40; deriveA.age = 20; DeriveB deriveB; deriveB.base.vptrTable.eat = bEat; deriveB.base.vptrTable.play = bPlay; deriveB.base.age = 40; deriveB.age = 21; base = (Base *)&deriveA; base->vptrTable.eat(); base->vptrTable.play(); cout<<"age:"<<base->age<<endl; cout<<"---------------------------------------------\n"; base = (Base *)&deriveB; base->vptrTable.eat(); base->vptrTable.play(); cout<<"age:"<<base->age<<endl; return a.exec(); }
完整代码如下:
#include <QCoreApplication> #include <iostream> using namespace std; typedef void (*EatPtr)(); typedef void (*PlayPtr)(); typedef struct _virtualPtrTable{ EatPtr eat; PlayPtr play; }VPtrTable; typedef struct _base{ VPtrTable vptrTable; int age; }Base; typedef struct _deriveA{ Base base; int age; }DeriveA; typedef struct _deriveB{ Base base; int age; }DeriveB; /** 基类的实现函数 **/ void baseEat(){ cout<<"基类在吃饭....."<<endl; } void basePlay(){ cout<<"基类在玩耍....."<<endl; } /** 派生类A的实现函数 **/ void aEat(){ cout<<"子类A在吃饭....."<<endl; } void aPlay(){ basePlay(); } /** 派生类B的实现函数 **/ void bEat(){ cout<<"子类B在吃饭....."<<endl; } void bPlay(){ basePlay(); } int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); Base *base; DeriveA deriveA; deriveA.base.vptrTable.eat = aEat; deriveA.base.vptrTable.play = aPlay; deriveA.base.age = 40; deriveA.age = 20; DeriveB deriveB; deriveB.base.vptrTable.eat = bEat; deriveB.base.vptrTable.play = bPlay; deriveB.base.age = 40; deriveB.age = 21; base = (Base *)&deriveA; base->vptrTable.eat(); base->vptrTable.play(); cout<<"age:"<<base->age<<endl; cout<<"---------------------------------------------\n"; base = (Base *)&deriveB; base->vptrTable.eat(); base->vptrTable.play(); cout<<"age:"<<base->age<<endl; return a.exec(); }
运行效果:
写的比较简单,欢迎来探讨。
如果你觉得有所收获,记得点赞呀~~