C++的三大特性是什么?封装、继承与多态,那么今天这篇文章小编就来介绍一下,如何用C语言实现C++的这三个特性。
1.封装
何为封装?
在面向对象的思想中,将数据和对数据的操作封装在一起——即类。
类只对外界开放接口(即有权访问的函数接口),而将接口的实现细节和该类的一些属性(变量)隐藏起来,达到数据的抽象性(使具有相同行为的不同数据可以抽象为同一个类)、隐藏性和封装性。
我们知道,C语言中有struct结构体类型,能够将多种数据类型封装在一起,然而如何将对数据的操作一起封装进来呢?——函数指针。
对,显然我们可以使用函数指针。如下就是名为pfun,指向一个返回值为空、形参列表为空的函数指针:
函数指针格式简介
那么问题已经得到解决:将类中的函数以函数指针的形式存放在C的结构体中,即可实现封装(此处未讨论访问权限问题,小编仍在思考较好的方法,大家如果有好的建议记得留言噢n(*≧▽≦*)n!)
如下图所示,结构体AchievePackage中有成员变量_a和两个函数指针,在InitStruct函数中被赋予两个函数的地址(函数名即为其地址,也可为&fun1,得到的值一样),故在此处InitStruct函数相当于该结构体的构造函数,既可以初始化其成员变量_a的值,也在对象定义的同时为其函数指针赋值(需显示调用)
C语言实现封装详解
2.继承
顾名思义,就像孩子会继承父母的一些性格或特点,两个类如果存在继承关系,其子类必定具有父类的相关属性(即变量)和方法(即函数)。
在C++中,如果想要类B去继承类A,需要在B定义时增加如下语句:
C++继承简介
那么C语言要如何实现此特性呢?讲到这里,大家可以想到什么?
【组合】:如果仅仅是想用一个已有类的一些方法去辅助新生成的类,组合是一个很好的方案,即在新类中直接定义已有类的对象,通过该对象的一些方法去辅助新类的操作。
它与继承相比:
-
继承即“属于(is a)”关系,而组合是“包含(has a)”关系。
-
继承是复用原类,并对其进行扩展,而包含仅仅是组合在一起。
-
如我们可以用普通车辆(所有车的共同特性)扩展(继承)出公交车、面包车、越野车等等,它们都属于普通车辆;也可以用发动机、排气筒、轮子等组合出一辆车,它们都包含在车辆中。
下面我们就用“组合”去实现一下C语言中的继承:
C语言实现继承代码
3.多态
在C++中,多态是通过父类的指针或引用,调用了一个在父类中是virtual类型的函数,实现动态绑定机制。我们知道,若想使用父类的指针/引用调用子类的函数,需要在父类中将其声明为虚函数(virtual),且必须与子类中的函数参数列表相同(包括参数个数、类型、顺序),返回值也相同(若不同为协变的情况,需要各自返回各自类的指针/引用)。
那么如何用C实现多态?
-
C++的多态是通过覆盖实现的,即父类的函数被子类覆盖了!
-
父类的该函数为虚函数,告诉父类的指针/引用,你调用这个函数的时候必须看一看你绑定的对象到底是哪个类的对象,然后去那个类里调用该函数!
So,覆盖!我们用值的覆盖,去改变函数指针,是否可以达到多态的效果呢?
C语言实现多态代码
以上,便是C语言实现C++三大特性的全部内容。
需要注意的是:
-
毕竟是用C语言去实现本不属于它的特性,一定会存在不可避免的付出,但我们可以通过不同的处理,尽量降低付出成本。
-
本文中未对访问限定符public、protected、private进行讨论