嵌入式C-实现面向对象编程

我们走过的路,其实每一步都算数。

这是我的第六篇原创文章

最近公司看aworks驱动框架,看到框架中使用了大量的C语言面向对象编程和链表,他们将所有的接口都封装成设备。我们都知道面向对象编程有三个特征---封装,继承,多态。

在写这篇笔记前,还是要感谢强。周四那天晚上,强和我说了AWorks中继承的问题,今天上午在写代码测试时候,也是他指点我实现面向对象的问题。

这里有几个前提,就是要了解:在C语言中,一个结构体就相当于一个类,结构体实例化之后就是一个对象。结构体中的成员类似类中的成员,结构体中的函数指针类似类方法。

我们先来说说C实现面向对象的继承问题。

先说说继承的基本概念,在程序中,继承描述的是事物之间的所属关系,例如猫和狗都属于动物,程序中便可以描述为猫和狗继承自动物;同理,波斯猫和巴厘猫都继承自猫,而沙皮狗和斑点狗都继承足够,如下如所示:

这里我用经常看到的学生类来讲解这个框架,先来看一下我写简单的代码框架:

这个也容易看出学生类继承了person类,可以访问person中的成员(公有 public),这个好理解。

下面我们来写一个函数,给所有的成员赋值,并且打印出来,具体如下:

在上面的的函数中,我们在main函数里面实例化了一个对象p1;

function中,我们将p1这个对象进行了强制类型转化为person类,传入,通过子类给父类成员赋值和自生类赋值。

为什么能这样转化呢?这就是我们这篇文章中的重点。你可以在这儿停下来想想为什么在继续看下去。

我先来画一张内存分布图,从内存的角度容易理解点,如下图:

这个类似与int类型我们强制类型转化为char,差不多一个道理。为什么要用强制类型转化呢?我想是为了跟加贴近C++这样的面向对象的方法,访问父类就像访问自己成员一样方便,这样可以少写一层关系。

从上面一个小例子我们很好的理解了面向对象中继承关系,在AWorks中并不是这么简单的使用,还包括了继承和封装,并且上面的例子中也只有成员,并没有方法。

我们先创建3个文件,oop.c,oop.h和main.c下面我们结合封装讲解稍微复杂点的框架。oop.h是给用户的接口,oop.c一般不对外。

oop.h文件

在在上诉的文件中,我们看到在student类中有一个结构体指针,是info,但是我们看不见,因为这个结构体在opp.c中,类似一个私有变量(方法)。

观察这个文件中的内容,可见,向用户提供的接口只有有两个,类似与C++中的构造函数。当然也可以写两个析构函数,这个我就给个示例,有兴趣可以自己实现下,后面有实现过程。

oop.c文件

在程序中我们为了像 C++ 中一样通过类实例来访问成员函数,必须将结构体内的函数指针的第一个参数定义为自身的指针,在调用时传入函数指针所属的结构体实例。这是因为 C 语言中不存在像 C++ 中那样的 this 指针,如果我们不显式地通过参数提供,那么在函数内部就无法访问结构体实例的其它成员。

程序中还发现,我们使用的是结构体指针,显然,我们不可以直接访问他,只能通过结构体中的方法访问,这个就类似的完成一个面向对象的一个封装过程。

好了,看到这里可能有点懵,别急,我们再看看最后一个文件。

main.c

在main函数中,我们只是定义了一个student对象,为什么他可以访问父类,也是因为继承了父类的方法和成员,这在内存中体现的。在i子类构造的时候有一句话很重要:

为什么要这句,这里我们再画一个内存分布图来理解下:

到这里我们已经知道如何在 C 语言中实现一个基本的“类”了。接下来再回过头捋一捋前面提到的。

使用子类的对象,可以像子派生类自己的成员一样访问父类的成员。这个有点变化,还是只能通过子类实例的第一个成员来访问基类的成员(通过指针强制转换的话可以直接访问),切记,必须在第一个成员,否则他们不是共用一个地址空间,当然也可以不用这样,只是多调用一层关系罢了。这只是一种方法。

上面只是在看AWorks框架看到的一些方法,在强的指导下,了解了一些原理,自己写了个简单的测试函数印证自己想的。在这里记录一下。

C语言还是很神奇的东西,自己不会的还有很多,慢慢的学吧,也要开始尝试看Linux源码了。

如果上面文章有写的不到位的地方,可以在后台给我留言,咱们交流交流。

-END-

转载是一种动力 分享是一种美德

感谢您抽出·来阅读此文

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180721G1LOGO00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券