C语言实现多态

C语言实现多态

原文

1.C++和C的区别

C语言是面向过程的语言,而C++是面向对象的过程。

什么是面向对象和面向过程?

面向过程就是分析解决问题的步骤,然后用函数把这些步骤一步一步的进行实现,在使用的时候进行一一调用就行了,注重的是对于过程的分析。面向对象则是把构成问题的事进行分成各个对象,建立对象的目的也不仅仅是完成这一个个步骤,而是描述各个问题在解决的过程中所发生的行为。

面向对象和面向过程的区别?

面向过程的设计方法采用函数来描述数据的操作,但将函数与操作的数据进行分离开来。
面向对象的设计方法是将对象和数据进行封装起来成为一个整体。
面向过程以设计步骤为过程,后期难以维护。
面向对象设计以数据为中心,数据相对与功能来说具有较强的稳定性更加易于维护。

面向对象的三大特征

封装:
对于封装来说就是数据与具体操作实现的代码都放在某个对象的内部,使这些代码的具体细节不被外界发现,只留下一些接口供外部来使用,而不能一任何的形式来对象内部的实现。使用封装能够隐藏具体的实现的细节,使代码更加易于维护并且保证了系统的安全性。
继承:
继承机制是面向对象程序设计使代码进行复用的最重要的手段,他允许程序员在保证类原有类特性的基础上进行扩展来增加功能。这样新产生的类就被称为派生类,继承就可以表现面向对象机制的的层次结构。
多态:
多态简单点说就是“一个接口,多种实现”,就是同一种事物表现出的多种形态。多态在面向对象语言中是指:接口多种的不同实现方式。也就是复用相同接口,实现不同操作。

C++多态支持两种多态性,编译时多态运行时多态。编译时多态是通过重载函数来实现的,运行时多态是通过虚函数来实现的。静态多态:编译器在编译期间完成,编译器根据函数实参的类型(可能会隐式类型转换),可推断出要调用哪个函数,如果有对应的函数就调用相应的函数,否则就报一个编译错误。动态多态:在函数执行期间(非编译期)判断所引用对象的实际类型,根据实际类型的调用相应的方法。使用virtual关键字修饰类的成员函数,指明该函数为虚函数,派生类需要重新实现,编译器将实现动态绑定。

2.C模拟实现多态

关于c++如何实现多态可参考上篇文章

我们知道在C语言中是没有class类这个概念的,但是有struct结构体,我们可以考虑使用struct来模拟;但是在C语言的结构体内部是没有成员函数的,如果实现这个父结构体和子结构体共有的函数呢?我们可以考虑使用函数指针来模拟。但是这样处理存在一个缺陷就是:父子各自的函数指针之间指向的不是类似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
31
32
33
34
35
36
37
38
39
40
41
//C实现动态,用到函数指针

typedef void(*FUN)();//重定义一个函数指针类型

//父类
struct Base
{
FUN _f;
};

//子类
struct Derived
{
Base _b;//在子类中定义一个基类的对象即可实现对父类的继承
};


void FunB()
{
printf("%s\n", "Base::fun()");
}
void FunD()
{
printf("%s\n", "Derived::fun()");
}

void Test2()
{
Base b;//父类对象
Derived d;//子类对象

b._f = FunB;//父类对象调用父类同名函数
d._b._f = FunD;//子类调用子类的同名函数

Base *pb = &b;//父类指针指向父类对象
pb->_f();

pb = (Base *)&d;//让父类指针指向子类的对象,由于类型不匹配所以要进行强转
pb->_f();

}

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!