当前位置:首页 > 公众号精选 > 嵌入式大杂烩
[导读]前言 上次整理了一篇关于面向对象的笔记:《什么是面向对象?》。简单地分享了面向对象的一些基础知识。 C语言虽不是面向对象的语言,但也可以使用面向对象的思想来设计我们的程序。 C语言 + 面向对象的思想在我们嵌入式中使用得很广泛,主要优点就是能使我们

前言

上次整理了一篇关于面向对象的笔记:《什么是面向对象?》简单地分享了面向对象的一些基础知识。

C语言虽不是面向对象的语言,但也可以使用面向对象的思想来设计我们的程序。

C语言 + 面向对象的思想在我们嵌入式中使用得很广泛,主要优点就是能使我们的软件拓展性更好、更易读、更容易维护等。

因为这一块知识也比较重要,属于通用知识,所以打算分享几篇笔记与大家一起学习一下。

当然,C语言并不是面向对象的语言,要想完全实现与C++一样的一些面向对象的特性会比较难。所以我们分享的内容也面向基础、实用的为主。

本篇笔记分享的是:封装与抽象

封装与抽象

封装性是面向对象编程的三大特性(封装性、继承性、多态性)之一,但也是最重要的特性。封装+抽象相结合就可以对外提供一个低耦合的模块。

数据封装是一种把数据和操作数据的函数捆绑在一起的机制,数据抽象是一种仅向用户暴露接口而把具体的实现细节隐藏起来的机制。

在C语言中,数据封装可以从结构体入手,结构体里可以放数据成员和操作数据的函数指针成员。当然,结构体里也可以只包含着要操作的数据。

下面以一个简单的实例作为演示。

设计一个软件模块,模块中要操作的对象是长方形,需要对外提供的接口有:

1、创建长方形对象;

2、设置长、宽;

3、获取长方形面积;

4、打印长方形的信息(长、宽、高);

5、删除长方形对象。

下面我们来一起完成这个demo代码。首先,我们思考一下,我们的接口命名大概是怎样的?其实这是有规律可循的,我们看RT-Thread的面向对象接口是怎么设计的:


我们也模仿这样子的命名形式来给我们这个demo的几个接口命名:

1、rect_create
2、rect_set
3、rect_getArea
4、rect_display
5、rect_delete

我们建立一个rect.h的头文件,在这里声明我们对外提供的几个接口。这时候我们头文件可以设计为:


这样做是没有什么问题的。可是数据隐藏得不够好,我们提供给外部用的东西要尽量简单。

我们可以思考一下,对于C语言的文件操作,C语言库给我们提供怎么样的文件操作接口?如:

左右滑动查看全部代码>>>

FILE *fopen(const char *pathname, const char *mode);
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);


我们会创建一个文件句柄(描述符),然后之后只要操作这个文件句柄就可以,我们不用关心FILE具体是怎么实现的。

什么是句柄?看一下百度百科的解释:


我们也可以创建我们的对象句柄,对外提供的头文件中只需暴露我们的对象句柄,不用暴露具体的实现。以上头文件rect.h代码可以修改为:


这里用到了void*其为无类型指针,void *可以指向任何类型的数据。然后具体要操作怎么样的结构体可以在.c中实现:


下面我们依次实现上述五个函数:

1、rect_create函数

左右滑动查看全部代码>>>

/* 创建长方形对象 */
HandleRect rect_create(const char *object_name)
{
 printf(">>>>>>>>>> %s: %s (line: %d) <<<<<<<<<<\n", __FILE__, __FUNCTION__, __LINE__);

 /* 给rect结构体变量分配内存 */
 pRect rect = (pRect)malloc(sizeof(Rect));
 if (NULL == rect)
 {
  free(rect);
  rect = NULL;
  abort();
 }
 /* 给rect->object_name字符串申请内存 */
 rect->object_name = (char*)malloc(strlen(object_name) + 1);
 if (NULL == rect->object_name)
 {
  free(rect->object_name);
  rect->object_name = NULL;
  abort();
 }

 /* 给结构体各成员进行初始化 */
 strncpy(rect->object_name, object_name, strlen(object_name) + 1);
 rect->length = 0;
 rect->width = 0;
 
 return ((HandleRect)rect);
}

rect对象创建函数:首先分配内存,然后对rect结构体各个成员进行赋值操作,最后返回的是rect对象句柄。rect的object_name成员是个字符串,因此要单独分配内存。

2、rect_set函数

左右滑动查看全部代码>>>

/* 设置长方形对象长、宽 */
void rect_set(HandleRect rect, int length, int width)
{
 printf(">>>>>>>>>> %s: %s (line: %d) <<<<<<<<<<\n", __FILE__, __FUNCTION__, __LINE__);
 if (rect)
 {
  ((pRect)rect)->length = length;
  ((pRect)rect)->width = width;
 }
}

3、rect_getArea函数

左右滑动查看全部代码>>>

/* 获取长方形对象面积 */
int rect_getArea(HandleRect rect)
{
 return ( ((pRect)rect)->length * ((pRect)rect)->width );
}

4、rect_display函数

左右滑动查看全部代码>>>

/* 打印显示长方形对象信息 */
void rect_display(HandleRect rect)
{
 printf(">>>>>>>>>> %s: %s (line: %d) <<<<<<<<<<\n", __FILE__, __FUNCTION__, __LINE__);
 if (rect)
 {
  printf("object_name = %s\n", ((pRect)rect)->object_name);
  printf("length = %d\n", ((pRect)rect)->length);
  printf("width = %d\n", ((pRect)rect)->width);
  printf("area = %d\n", rect_getArea(rect));
 }
}

5、rect_delete函数

左右滑动查看全部代码>>>

void rect_delete(HandleRect rect)
{
 printf(">>>>>>>>>> %s: %s (line: %d) <<<<<<<<<<\n", __FILE__, __FUNCTION__, __LINE__);
 if (rect)
 {
  free(((pRect)rect)->object_name);
  free(rect);
  ((pRect)rect)->object_name = NULL;
  rect = NULL;
 }
}

rect对象删除函数:主要是对创建函数中的malloc申请的内存做释放操作。

可以看到这五个对象接口主要包含三类:创建对象函数、操作函数、删除对象函数。这里的操作函数就是rect_set函数、rect_getArea函数与rect_display函数,当然还可以有其它更多的操作函数。

操作函数的特点是至少需要传入一个表示对象的句柄,在函数的内部再做实际数据结构的转换,然后再进行相应的操作。

6、测试程序:

左右滑动查看全部代码>>>

#include <stdio.h>
#include <stdlib.h>
#include "rect.h"

int main(void)
{
 HandleRect rect = rect_create("rect_obj");  // 创建Rect对象句柄
 rect_set(rect, 205);         // 设置     
 rect_display(rect);            // 打印显示 
 rect_delete(rect);             // 删除Rect对象句柄 
 
 return 0;
}

运行结果:


在基于对象的编程中,封装性是最基础也最重要的内容。其对象主要包含两方面内容:属性方法

在基于C语言的对象编程中,可以使用句柄来表示对象,即句柄指向的数据结构的成员代表对象的属性,实际操作句柄的函数则表示对象的方法。

以上就是本次的分享,如有错误,欢迎指出!

本篇笔记相关代码可在公众号后台回复关键字:C语言对象编程第一弹:封装与抽象,即可获取。

猜你喜欢

什么是动态链接与静态链接?

STM32的ISP下载的原理是什么呢?


为了便于公众号读者交流学习,小编创建了相关相关交流群。坑位有限,感兴趣的朋友可以扫码下方二维码加我微信,由我邀请入群:


欢迎大家进群交流、共同进步。同时,我也会关注一些大家问的一些问题,从中挑选一些具有代表性的、并且在我知识范围内的问题写出相关文章做分享。


免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

9月2日消息,不造车的华为或将催生出更大的独角兽公司,随着阿维塔和赛力斯的入局,华为引望愈发显得引人瞩目。

关键字: 阿维塔 塞力斯 华为

加利福尼亚州圣克拉拉县2024年8月30日 /美通社/ -- 数字化转型技术解决方案公司Trianz今天宣布,该公司与Amazon Web Services (AWS)签订了...

关键字: AWS AN BSP 数字化

伦敦2024年8月29日 /美通社/ -- 英国汽车技术公司SODA.Auto推出其旗舰产品SODA V,这是全球首款涵盖汽车工程师从创意到认证的所有需求的工具,可用于创建软件定义汽车。 SODA V工具的开发耗时1.5...

关键字: 汽车 人工智能 智能驱动 BSP

北京2024年8月28日 /美通社/ -- 越来越多用户希望企业业务能7×24不间断运行,同时企业却面临越来越多业务中断的风险,如企业系统复杂性的增加,频繁的功能更新和发布等。如何确保业务连续性,提升韧性,成...

关键字: 亚马逊 解密 控制平面 BSP

8月30日消息,据媒体报道,腾讯和网易近期正在缩减他们对日本游戏市场的投资。

关键字: 腾讯 编码器 CPU

8月28日消息,今天上午,2024中国国际大数据产业博览会开幕式在贵阳举行,华为董事、质量流程IT总裁陶景文发表了演讲。

关键字: 华为 12nm EDA 半导体

8月28日消息,在2024中国国际大数据产业博览会上,华为常务董事、华为云CEO张平安发表演讲称,数字世界的话语权最终是由生态的繁荣决定的。

关键字: 华为 12nm 手机 卫星通信

要点: 有效应对环境变化,经营业绩稳中有升 落实提质增效举措,毛利润率延续升势 战略布局成效显著,战新业务引领增长 以科技创新为引领,提升企业核心竞争力 坚持高质量发展策略,塑强核心竞争优势...

关键字: 通信 BSP 电信运营商 数字经济

北京2024年8月27日 /美通社/ -- 8月21日,由中央广播电视总台与中国电影电视技术学会联合牵头组建的NVI技术创新联盟在BIRTV2024超高清全产业链发展研讨会上宣布正式成立。 活动现场 NVI技术创新联...

关键字: VI 传输协议 音频 BSP

北京2024年8月27日 /美通社/ -- 在8月23日举办的2024年长三角生态绿色一体化发展示范区联合招商会上,软通动力信息技术(集团)股份有限公司(以下简称"软通动力")与长三角投资(上海)有限...

关键字: BSP 信息技术
关闭
关闭