成都网站设计制作公司/百度发布信息的免费平台
正文
大家好,我是bug菌!
最近挺忙的,在上周直播中也跟大家提到,今年做的几个新项目也都接近尾声,与此同时开始对各个地区的老客户进行需求采集和未来项目规划。所以今天能够看到bug菌的这篇原创文章,应该是幸福感满满的。
当然马上中秋小长假了,祝大家中秋节快乐~
今天的主题算是之前文章的拓展,如下:
☞ 如何隐藏"结构体对象"成员?
在文章最后bug菌提到之前的隐藏结构体成员的方法是一种完全私有的封装无法做到"公私分明",这样通过函数调用在MCU中会存在较大的开销。
1
原理与技巧
那时候bug菌就在想有什么办法可以做到私有成员与公共成员区别对待呢?
既然.h文件中的不完全类型仅仅只是一个啥也不含的结构体空壳,那么根据结构体的内存模型以及我们平时经常提到的C语言面向对象设计中的继承处理。
于是便编写了如下代码来验证我的想法:
参考代码:
/************filename: App.c*************/ typedef struct _tag_StObj stObj;
struct _tag_StObj
{int member1;int member2;
};/********************************** * Function : sCreate* Note :创建对象* Author: bug菌**********************************/
stObj * sCreate(int member1,int member2)
{static stObj staticObj;staticObj.member1 = member1;staticObj.member2 = member2;return &staticObj;
}/********************************** * Function : sAdd* Note :对象方法* Author: bug菌**********************************/
int sAdd(stObj *pObj)
{return (pObj->member1 + pObj->member2);
}
/************filename: App.h*************/
#ifndef __APP_H__
#define __APP_H__//自定义结构体声明
typedef struct _tag_StObj stObj;
struct _tag_StObj
{int member1;
};//extern interface
extern stObj * sCreate(int member1,int member2);
extern int sAdd(stObj *pObj); #endif
/**********main.c file***********/
#include <stdio.h>
#include "App.h"int main(void)
{stObj *Obj;Obj = sCreate(3,5); //内部构造结构体 printf("member1 = %d\n",Obj->member1); //调用OK,member1被公开//printf("member2 = %d\n",Obj->member2); 调用失败,因为member2被隐藏printf("result = %d\n",sAdd(Obj)); //调用相应的接口 return 0;
}
输出结果:
从输出结果上来看编译正常,且输出了正确的结果,member1可被外界直接访问,而member2只能通过App.c内部直接访问,或者通过定义外部函数接口进行间接访问,否则就会报错。
一顿猛如虎的操作竟然验证了自己的一些想法。
2
优化版本
后来又想了想,如果成员比较多,不是特别好管理,于是尝试了一个更好的成员管理方式:
参考代码:
/************filename: App.h*************/
#ifndef __APP_H__
#define __APP_H__typedef struct _tag_Stpublic stpublicObj;
struct _tag_Stpublic
{int member1;int member2;
};typedef struct _tag_StObj stObj;
struct _tag_StObj
{stpublicObj public;
};//interface
extern stObj * sCreate(int member1,int member2);
extern int sAddprivate(stObj *pObj);
extern int sAddpublic(stObj *pObj);#endif
/************filename: App.c*************/
//#include "App.h"typedef struct _tag_Stpublic stpublicObj;
struct _tag_Stpublic
{int member1;int member2;
};typedef struct _tag_Stprivate stprivateObj;
struct _tag_Stprivate
{int member1;int member2;
};typedef struct _tag_StObj stObj;
struct _tag_StObj
{stpublicObj public;stprivateObj private;
};/********************************** * Function : sCreate* Note :创建对象* Author: bug菌**********************************/
stObj * sCreate(int member1,int member2)
{static stObj staticObj;staticObj.private.member1 = member1;staticObj.private.member2 = member2;return &staticObj;
}/********************************** * Function : sAdd* Note :对象方法* Author: bug菌**********************************/
int sAddprivate(stObj *pObj)
{return (pObj->private.member1 + pObj->private.member2);
}/********************************** * Function : sAdd* Note :对象方法* Author: bug菌**********************************/
int sAddpublic(stObj *pObj)
{return (pObj->public.member1 + pObj->public.member2);
}
/**************main.c file****************/
#include <stdio.h>
#include "App.h"int main(void)
{stObj *Obj;Obj = sCreate(3,5); //内部构造结构体 Obj->public.member1 = 10;Obj->public.member1 = 6;Obj->public.member2 = 10;printf("member1 = %d\n",Obj->public.member1); //调用OK,member1被公开printf("member2 = %d\n",Obj->public.member2); //调用OK,member1被公开// printf("member1 = %d\n",Obj->private.member1); //调用失败,因为member1被隐藏
// printf("member2 = %d\n",Obj->private.member2); //调用失败,因为member2被隐藏printf("private result = %d\n",sAddprivate(Obj)); //调用相应的接口 printf("public result = %d\n",sAddpublic(Obj)); //调用相应的接口 return 0;
}
输出结果:
编译OK,完工,是不是感觉有一股C++的味道了,如果你还没有看懂的话,记得多看几遍,因为这种处理方式算是非常常见的~
最后
好了,本来回得比较晚,这不一眨眼的功夫凌晨了,如果你觉得有所收获,一定记得点个赞~
中秋小长假就不更新了,大家可以回味一下bug菌之前的文章~
推荐专辑 点击蓝色字体即可跳转
☞ MCU进阶专辑
☞ 嵌入式C语言进阶专辑
☞ “bug说”专辑