C实现C++的继承和多态
第一个版本的比较完全,第二个版本的比较好理解,注意,第二个版本细节上是有问题的,细节上没有体现出派生类重载父类,但是大意上还是体现出虚表是发生多态的关键。
关于细节:
继承:
继承是指子类拥有父类的特性,只要把父类原原本本的放入子类中即可,即:子结构体包含父结构体即可,案例2并未体现出来,懒得改了。
多态:
多态是指子类拥有父类的特性或者父类拥有子类的特性,这里是通过虚表来实现的,案例2的虚表写的也有问题,这里由于是继承,应该使用父类的虚表,但是由于并未包含父类,因此这里案例2只包含了一张子类特有的虚表。实际C++的实现应该是包含父类,然后再父类的虚表基础上进行虚函数替换,得到一张新的虚表,进而实现多态。
为什么案例二问题这么多,还是要给出案例2呢?
因为案例二是我自己写的,第一次写,难免有许多不足道的地方,留着以后学习批判用。
案例一:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
| #include <stdio.h>
typedef struct fvtp{ void*(*Fpfun1)(void*); void*(*Fpfun2)(void*); }fvtp; typedef struct cvtp{ fvtp fvtp1; void(*Cpfun)(void); }cvtp;
typedef struct father{ int data; fvtp* fp; void*(*Funtion)(void*); }father; typedef struct child{ father base_f; int data; }child;
void* Fpfun1(void* s){ char* str = (char*)(s); printf("the Father virtual Funtion One!\n"); printf("the input string = %s\n",str); return (void*)(NULL); } void* Fpfun2(void* s){ char* str = (char*)(s); printf("the virtual funtion Two!\n"); printf("the input string = %s",str); return (void*)(NULL); } void Cpfun1(){ printf("the child virtual funtion One!\n");
} void* Cpfun2(void* s){ char * str = (char*)(s); printf("the child virtual funtion Two!\n"); printf("the input string = %s\n",str); return (void*)(NULL); } void* Cpfun3(void* s){ char * str = (char*)(s); printf("the child virtual funtion Three!\n"); printf("the input string = %s",str); return (void*)(NULL); }
fvtp g_fvtp = {&Fpfun1,&Fpfun2}; cvtp g_cvtp = {{&Cpfun2,&Cpfun3},&Cpfun1};
void initFather(father* f){ f->data = 20; f->fp = &g_fvtp; } void initChild(child* c){ c->data = 10; initFather((father*)c); c->base_f.fp = (fvtp*)&g_cvtp; }
void initFC(father* f){ f->data = 10; f->fp = (fvtp*)&g_cvtp; }
void test(father* f){ fvtp* fv = (fvtp*)f->fp; (*fv).Fpfun2("hello"); }
int main(int argc, const char * argv[]) { father f; child c; initChild(&c); c.base_f.fp->Fpfun1(">"); initFC(&f); cvtp* cvp = (cvtp*)f.fp; cvp->fvtp1.Fpfun1("?"); return 0; }
|
案例二:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
|
#include <stdio.h> #include <stdlib.h>
typedef struct DesVT{ void (*PrintClassMessage)(void*); int (*CostPerformance)(int,int); void*(*RetainInterface)(void*); }DesVT;
typedef struct LapVT{ DesVT dvt; void (*UniqueFuntion)(int,int); }LapVT;
typedef struct Desktop{ int cost; int value; DesVT dvt; void (*Desktop)(int); }desktop;
typedef struct Laptop{ int cost; int value; LapVT lvt; void(*Laptop)(int); }laptop;
void PrintClassMessage(void* s){ char* str = (char*)(s); printf("The computer is %s\n",str); }
int CostPerformance(int cost,int value){ int res = 0; res = value/cost; printf("the cost performance = %d\n",res); return res; }
void* RetainInterface(void* package){ printf("do nonthing\n"); return (void*)(NULL); }
void Desktop(int value){ printf("destop value = %d\n",value); }
void UniqueFuntion(int a,int b){ printf("UniqueFuntion do nonthing\n"); }
void* overloading(void* package){ printf("打印重载函数\n"); return (void*)(NULL); }
void InitDesktop(desktop* dp){ dp->dvt = *(DesVT*)malloc(sizeof(DesVT)); dp->dvt.CostPerformance = &CostPerformance; dp->dvt.PrintClassMessage = &PrintClassMessage; dp->dvt.RetainInterface = &RetainInterface; dp->Desktop = &Desktop; }
void InitLaptop(laptop* lp){ lp->value = 3333; lp->cost = 6000; lp->lvt = *(LapVT*)malloc(sizeof(LapVT)); InitDesktop((desktop*)lp); lp->lvt.dvt.RetainInterface = &overloading; lp->lvt.UniqueFuntion = &UniqueFuntion; }
void InitDesktopToLaptop(desktop* dp){ dp->cost = 2000; dp->value = 100; dp->dvt = *(DesVT*)malloc(sizeof(DesVT)); InitDesktop(dp); dp->dvt.RetainInterface = &overloading; }
void TestDTD(){ desktop dp; InitDesktop(&dp); dp.dvt.PrintClassMessage("Desktop"); dp.Desktop(20); }
void TestLTT(){ }
void TestDTL(){ desktop dp; InitDesktopToLaptop(&dp); dp.Desktop(dp.value); dp.dvt.RetainInterface(""); }
void TestLTD(){ }
int main(){ TestDTL(); return 0; }
|