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) <<<<<<<<<< ", __FILE__, __FUNCTION__, __LINE__); /* 给rect结构体变量分配内存 */ pRect rect = (pRect)malloc(sizeof(Rect)); if (NULL == rect) { printf("rect memory malloc failed! "); abort(); } /* 给rect->object_name字符串申请内存 */ rect->object_name = (char*)malloc(strlen(object_name) + 1); if (NULL == rect->object_name) { printf("rect->object_name memory malloc failed! "); 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) <<<<<<<<<< ", __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) <<<<<<<<<< ", __FILE__, __FUNCTION__, __LINE__); if (rect) { printf("object_name = %s ", ((pRect)rect)->object_name); printf("length = %d ", ((pRect)rect)->length); printf("width = %d ", ((pRect)rect)->width); printf("area = %d ", rect_getArea(rect)); } }5、rect_delete函数void rect_delete(HandleRect rect) { printf(">>>>>>>>>> %s: %s (line: %d) <<<<<<<<<< ", __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 #include #include "rect.h" int main(void) { HandleRect rect = rect_create("rect_obj"); // 创建Rect对象句柄 rect_set(rect, 20, 5); // 设置 rect_display(rect); // 打印显示 rect_delete(rect); // 删除Rect对象句柄 return 0; }运行结果:
在基于对象的编程中,封装性是最基础也最重要的内容。其对象主要包含两方面内容:属性与方法。在基于C语言的对象编程中,可以使用句柄来表示对象,即句柄指向的数据结构的成员代表对象的属性,实际操作句柄的函数则表示对象的方法。
以上就是本次的分享,如有错误,欢迎指出!谢谢
鹏博士智慧云事业部与阿里云达成数据库全面合作近年来,企业面临着复杂多变的内外部发展环境,数据作为企业的核心资产,如何最大化价值,数据库建设成为重要一环。伴随着中国企业上云步伐的加快,云数据库服务异军突起,成为行业趋势。在全面
北京电信通企业宽带可视化服务平台,品质安全无忧沃信通系列产品为鹏博士与北京联通联合推出品牌,电信通作为该品牌北京地区的唯一经销商,依托于鹏博士强大的运维支撑团队为用户提供一级云运营商品质的互联网接入产品。为什么选择电信通企业宽
鹏博士崔航让客户更专注于自己的业务云计算市场发展进入快车道,成为企业数字化转型的关键要素,这其中需要强大的网络能力支撑。云网协同的重要性逐渐凸显,这蕴含着巨大的行业价值,也要求相关企业紧密合作。在鹏博士总裁崔航看来
连锁企业怎么依靠云连锁服务走向巅峰?众所周知,连锁企业经营成功的要诀在于连锁复制扩张,而复制的前提是标准化,复制的最佳结果也是标准化,企业没有标准化,何来连锁复制。那企业的标准化是什么?以提高经济效益为目的,制定的各
亏损2。2亿翻身的鸿星尔克,背后的真相究竟是什么?自从河南遭受暴雨侵袭,各地都纷纷对河南伸出了援手。不少明星和公司纷纷捐款,献出了自己的一份力量。其中,鸿星尔克捐款5000万后爆红网络成了舆论焦点,频频登上微博热搜,一夜之间成了国
怎样打造面向未来的企业云办公?现如今,企业数字化转型的浪潮席卷各个行业,科技赋能对引领数字时代起到至关重要的作用,对企业而言,是机遇更是挑战。在网络安全协作绿色高效等领域不断创新,融合高新智能硬件设施软件应用服
鹏博士与汽配旺旺的上云故事疫情刚爆发的时候,所有汽配城都是不开门的,但生意还在继续。这个时候,传统的系统都在汽配城里,就无法开张。但如果使用的是云端SaaS系统,即便汽配城不开门,店家商品管理和服务也是在线
企业专线宽带和家庭宽带有什么不同?宽带主要分为专线(企业宽带)和家庭宽带两种,是运营商根据客户做的区分,并根据两者的需求点实施了不同的服务和政策,因此专线和家庭宽带在价格和速度上是有区别的。企业专线宽带是运营商为集
白露逢单,地上不干论天气对农业的重要性蒹葭苍苍,白露为霜。今日17点52分46秒,白露至。此时,夏季的闷热基本结束,逐渐转向秋季的凉爽,进入一年中最舒适的时节。白露之际,农业生产进入繁忙的秋收。既要做好秋季作物的管理,
小米有品硬核测评罗永浩的网易严选人体工学椅,为啥不建议买最近换了办公室,新的办公椅坐着贼难受,不少同事纷纷讨论买一把人体工学椅回来。首先敲定的就是罗永浩在网易严选多功能人体工学椅,有罗永浩坐镇,再加上便宜(仅999),这把椅子很快就火便
气候临界点到来,墨迹天气的新基建角色凸显气象是盐2021年,人类对这句话体会的尤为深刻,因为气候突变的常态化,迫使人们将查阅天气预报变成日常习惯。德国的洪灾,美国的暴风,希腊的烈火,巴西的冰雪,还有中国华北地区延续到10