用C实现面向对象之继承

本文介绍如何在C语言中模拟面向对象编程中的继承特性。通过结构体和函数指针,可以实现基类与派生类之间的关系,以及派生类对基类方法的重写。文章还提供了一个具体的经理类继承自职员类的例子。

之前讲了如何用C中的结构体和函数指针模拟封装特性。

下面进入下一个特性,继承。

我们回顾一下继承的概念,继承中的两个重要关系就是基类和派生类。派生类拥有基类的所有特征,并且可定义新的特征或者对基类的一些特性进行重定义。

接着上次讲的出现职员的例子,现在我们想在原来基础上增加一个经理类。经理类就是职员类的一个子类。而且我们预期做到经理不仅仅有职员的所有成员和方法,还有自己的方法:

void main()

{

    Employee a;

    a.Print(); 

    Manager m;      //创建经理类

    m.Print();    //这是原来职员类的方法

    m.ShowNum();//这是经理类特有的方法

}

 

那么在C中要如何实现呢?

我们仔细考虑,整个子类的数据在内存中分布情况。


我的理解是前面部分存放的是基类的部分,后面部分存放子类的部分。也就是说,如果不看一个子类的子类部分,我们可以完全把它当做一个基类来看。

需要注意继承与聚合这一概念的区别,聚合指的也是在一个结构体或者类中,存在另外的结构体或者类,比如飞机类中有发动机类、引擎类,但是并不是说飞机就是发动机或者引擎,而继承的概念是严格的is-a的关系,比如经理就是职员。

在设计C语言继承性的时候,我们需要做的就是把基础数据放在继承的结构的首位置即可。

这样,不管是数据的访问、数据的强转、数据的访问都不会有什么问题。也就是说,实际上是一种继承关系。

typedef struct Manager

{

    Employee base;

    void (*ShowNumOfEmp)(conststruct Manager*);//包含函数指针,用来访问这个函数

}Manager;

在构造函数中首先初始化基类成员,再初始化子类成员(这里假设有个子类函数指针)

//构造函数

ManagerManagerInit(char *name,intsalay,int num_of_emp)

{

    Manager ret;

    Employee base=EmployeeInit(name,salay);

    ret.base= base;

 

    ret.empnum=num_of_emp;

    ret.ShowNumOfEmp=ShowNumOfEmp;

 

    return ret;

}

 

 

以后,当我们需要把子类作为基类使用,只要把子类做一下强制类型转换,就可以。

 

当然,苛刻的C编译器不会允许你将2个看起来毫不相关的结构体来转换。



不要忘了我们强大的指针,有了它没有不可能。

我们制作一个宏,功能是通过制作强制把任何一个类型强制转换成基类。

#define GetEmployee(m) (*((Employee*)&m))

 

int main()

{

Employeea=EmployeeInit("Li Hua",1000);

Managerm=ManagerInit("XiaoMeng",10000,15);

 

a.Print(&a);

GetEmployee(m).Print(&GetEmployee(m));

 m.ShowNumOfEmp(&m);


EmployeeDestructor(a);

ManagerDestructor(m);

return 0;

}

 

运行结果:

 



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值