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{//father virtual table
void*(*Fpfun1)(void*);
void*(*Fpfun2)(void*);
}fvtp;
typedef struct cvtp{//child virtual table
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
/**
author:echo
time:2021.02.08 15:44
文件功能:C实现C++的继承和多态
类描述:laptop inherit desktop
**/

#include <stdio.h>
#include <stdlib.h>

typedef struct DesVT{//desktop virtual table
void (*PrintClassMessage)(void*);
int (*CostPerformance)(int,int);
void*(*RetainInterface)(void*);
}DesVT;

typedef struct LapVT{//laptop virtual table
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(){//test desktop to desktop
desktop dp;
InitDesktop(&dp);
dp.dvt.PrintClassMessage("Desktop");
dp.Desktop(20);
}

void TestLTT(){//test laptop to laptop
//和上面差不多,懒得写了
}

void TestDTL(){//test destop to laptop
desktop dp;
InitDesktopToLaptop(&dp);
dp.Desktop(dp.value);
dp.dvt.RetainInterface("");
}

void TestLTD(){//test laptop to desktop
//和InitDesktopToLaptop差不多,懒得写了
}

int main(){
TestDTL();
return 0;
}