一、C语言实现继承

原理:结构体组合类

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
//基类
typedef struct Base
{
//基类自身属性和方法
int b_val = 0;
void show()
{
printf("b_val:%d\n", b_val);
}
}Base;
typedef struct Son
{
//隐藏基类对象
Base base;
//派生类自身属性和函数
int s_val = 10;
void show()
{
printf("s_val:%d\n", s_val);
}

}Son;

int main()
{
Son s;
s.show();
s.base.show();
return 0;
}

在这里插入图片描述


二、C语言实现多态

(1)静态多态

原理:使用宏实现
静态多态:函数重载、运算符重载

1
2
3
4
5
6
7
8
9
#define SUM(A,B) (A)+(B)
int main()
{
printf("%d\n", SUM(10, 20));
string s1("hello");
string s2("world");
cout << SUM(s1, s2) << endl;
return 0;
}

在这里插入图片描述

(2)动态多态

注意:当公有继承的基类中不存在虚函数时,构建的对象内存中不含有__vfptr指针
原理:继承前提下,使用函数指针、虚表指针、理解构建虚函数表的过程

在实现动态多态前,我们先看看C++提供给我们的类结构是怎样的,以下面代码为例

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
class Base
{
private:
int b_val;
public:
Base(int x = 0): b_val(x){}
virtual void fun()
{
cout << "b_val:"<< b_val << endl;
}
};

class Son : public Base
{
private:
int s_val;
public:
Son(int x = 0) : Base(x), s_val(x + 10) {}
virtual void fun()
{
cout << "s_val:" << s_val << endl;
}
};
int main()
{
Son s;
return 0;
}

s对象内存结构:
在这里插入图片描述
实现代码:

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<iostream>
using namespace std;
//虚函数表结构
typedef struct vftable
{
void (*show)(void*); //根据所需自定义虚函数指针类型
}vftable;

//基类
typedef struct Base
{
//虚表指针
vftable* __vfptr;
//基类自身属性
int b_val = 0;
}Base;


typedef struct Son
{
//隐藏基类对象
Base base;

//派生类自身属性和函数
int s_val = 10;
}Son;

//基类函数
void ShowBase(void* th)
{
Base* bs = (Base*)th;
printf("b_val:%d\n", bs->b_val);
}
//派生类函数
void ShowSon(void* th)
{
Son* ss = (Son*)th;
printf("s_val:%d\n", ss->s_val);
}

//生成基类虚函数表
vftable base_vftable = { ShowBase};
//生成派生类虚函数表
vftable son_vftable = { ShowSon };

//基类构造函数
Base* create_Base(int val)
{
Base* tmp = (Base*)malloc(sizeof(Base));
memset(tmp, 0, sizeof(Base));
//设置虚表指针 指向基类虚函数表
tmp->__vfptr = &base_vftable;
//初始化Base中成员
tmp->b_val = val;
return tmp;
}
//派生类构造函数
Son* create_Son(int val)
{
Son* tmp = (Son*)malloc(sizeof(Son));
memset(tmp, 0, sizeof(Son));
//设置虚表指针
tmp->base.__vfptr = &son_vftable;

//初始化Base中成员
tmp->base.b_val = 0;
//初始化Son中成员
tmp->s_val = val;

return tmp;
}

int main()
{
//1.构造派生类对象
Son* sp = create_Son(10);

Base* bp = (Base*)sp;
//2.调用show函数指针 查派生类 虚函数表调用派生类的函数
bp->__vfptr->show((void*)sp);
free(sp);
bp = NULL;
sp = NULL;

return 0;
}

结果:使用基类指针成功调用派生类成员方法

在这里插入图片描述
对应内存结构:

在这里插入图片描述


参考文章:
C语言实现多态