当前位置: 首页 > news >正文

【UML+OOPC嵌入式C语言开发】使用C语言实现一个面向对象语言才能够实现的类

文章目录

  • 简述OOPC
  • 开发环境
  • 知识讲解
  • 函数示例
    • 类的实现示例
    • 接口实现示例

(前面两部分有点无聊,如果大家没兴趣看可以直接从知识讲解开始看


简述OOPC

  oopc,是一种轻量级的面向对象的C语言编程框架, LW_OOPC是Light-Weight Object-Oriented Programming in(with) C的缩写,总共一个.h文件, 20个宏, 约130行代码, 非常的轻量级, 但却很好的支持了很多面向对象的特性, 比如继承, 多态。 可以优美的实现面向接口编程。 这个框架是由台湾的高焕堂先生以及他的MISOO团队首创。


开发环境

  • 采用vscode为IDE
  • 使用makefile编写编译规则
  • 使用GCC编译器

  这里vscode的作用主要是编辑,哈哈哈。至于使用makefile编写编译规则,它既可以减少不必要的编译次数(文件数量较少体现不出),也解决了博主在vscode的同一个项目中,无法同时编译多个.c文件,总之,非常好用。😅🤣


知识讲解

面向对象语言开发特性:

  • 封装:根据职责将属性和方法封装到一个抽象的类中;
  • 继承:实现代码的重用,相同的代码不需要重复的写;
  • 多态:以封装和继承为前提,不同的子类对象调用相同的方法,产生不同的执行结果;

函数指针
  指针,形象化地来说就是一个指向一个空间的地址,也就是通过这个指针可以访问这个地址存储的内容。
  函数指针,是一个函数经过编译后,计算机会给它分配一段存储空间,而函数指针实际上是指向这段存储空间首地址的一个指针。 那么其函数名就表示函数的指针,代表了函数的起始地址。
  函数指针格式为 类型名 (*指针变量名) (函数参数列表),这里的类型名也可以理解为函数返回值的类型。
  例如:

  • 一个不带参数的函数指针可以表示为:void (*pFun) (void);
  • 一个带1个参数的函数指针可以表示为:void (*pFun) (int);
  • 一个带1个参数并且有返回值的函数指针可以表示为:int (*pFun) (int);

  当需要指向一个函数时,需要定义一个返回值、函数参数个数类型一致的函数,例如:

#include "stdio.h"
void fun(void)
{printf("this is fun\n");
}int main(void)
{void (*p) (void);p = fun;(*p)();return 0;
}

  其运行结果为:
在这里插入图片描述




那么一起来看看oopc是如何是如何进行面向对象开发的吧!🤤🤤🤤

关键字CLASS
  oopc中,一个类实际上是通过一个结构体实现。伪关键字CLASS实际上是通过define重新声明得到,实际上其定义为#define CLASS(type) typedef struct type type。(将其称为伪关键字是因为:在面向对语言中其确实是一个关键字,如java、python等确实有关键字class,而oopc的CLASS是通过声明得到,并不是C语言实际存在的关键字。)
  例如,定义一个类A:

// 类
CLASS (A)
{···// 属性及方法
};

关键字IMPLEMENTS
  implements关键字,在面向对象语言中,是继承一个接口比不可少的关键字(这里指java语言)。其实在基于oopc的C语言开发中,也是类似的。
  在oopc中,关键字IMPLEMENTS本质也是一个结构体,只不过就是将一个结构体变量名重新声明成IMPLEMENTS了,其声明为#define IMPLEMENTS(type) struct type type。(IMPLEMENTS也是一个伪关键字)
  明白了类的实现,接口的实现也就简单了,因为两者的本质都是结构体嘛。其实现为:

// 接口
INTERFACE (base)
{···// 接口的属性及方法
};

构造器CTOR
  在oopc中,构造器CTOR是一个非常重要的玩意。
  在oopc程序中,设计类是一件重要的工作,其目的是借之产生对象。“构造器”(Constructor)函数,可称之为“对象之母”,它能够依照类的定义产生对象。
  构造器CTOR在lw_oopc.h文件中的声明为:

#define CTOR(type)                                      \type* type##_new() {                                \struct type *cthis;                                 \cthis = (struct type*)malloc(sizeof(struct type));  \if(!cthis)                                          \{                                                   \return 0;                                       \}                                                   \type##_ctor(cthis);                                 \return cthis;                                       \
}

  不难看出:CTOR构造器的主要功能为,使用malloc函数分配内存空间给所声明的对象
  使用示例:

在头文件中使用

	// 类的声明class (A){void (*fun) (void);}// 外部声明extern A* A_new();

在.c文件中使用

	// 类的方法static void testFun(void){printf("this is a fun");}// 使用构造器构造类CTOR (A)FUNCTION_SETTING(fun,testFun);END_CTOR	

  在这里需要注意:外部声明函数extern A* A_new();声明时一定要使用类的名字,否则会出现报错。(这个声明可加可不加,网上也有很多帖子是使用ANew()来声明一个类的,可能是其修改了lw_oopc.h文件中的声明吧。)


函数示例

类的实现示例

main.c文件

#include <stdio.h>
#include "light.h"
#include "lw_oopc.h"
void main(void)
{printf("class light test\n");Light*n = (Light*)Light_new();n->init(n);printf("light state:%d\n",n->getState(n));n->setState(n,1);printf("new light state:%d\n",n->getState(n));
}

light.c文件

#include "light.h"
#include "stdio.h"
#include "lw_oopc.h"// 灯类的初始化
static void lightInit(void *light)
{Light*pthis = (Light*)light;pthis->state = 0;
}// 获取灯的状态
static int getLightState(void *light)
{Light*pthis = (Light*)light;return pthis->state;
}// 设置灯的状态
static void setLightState(void *light,int newState)
{Light*pthis = (Light*)light;pthis->state = newState;
}// 构造器  分配空间给类
CTOR (Light)FUNCTION_SETTING(init,lightInit);FUNCTION_SETTING(getState,getLightState);FUNCTION_SETTING(setState,setLightState);
END_CTOR

light.h文件

#ifndef  _LIGHT_H
#define  _LIGHT_H#include "lw_oopc.h"CLASS (Light)
{int state;void (*init) (void*);int (*getState) (void*);void (*setState) (void*,int newState);
};// 相当于重新new一个灯类
extern Light* Light_new();#endif // _DATA_H

vscode运行结果
在这里插入图片描述

接口实现示例

main.c文件

#include <stdio.h>
#include "lw_oopc.h"
#include "myInterface.h"// 接口测试
void main(void)
{// 圆类的实现circle*c = (circle*)circle_new();c->baseShape.init(c,"circle");c->baseShape.draw(c);c->vMove(c);// 正方形类的实现square* s = square_new();s->baseShape.init(s,"square1");s->baseShape.draw(s);s->vMove(s);
}

myInterface.h文件

#ifndef _MYINTERFACE_H
#define _MYINTERFACE_H#include "lw_oopc.h"// 接口
INTERFACE (baseShape)
{char name[10];void (*init) (void*,char*);void (*draw) (void*);
};// 圆类
CLASS (circle)
{IMPLEMENTS (baseShape);void (*vMove) (void*);
};
extern circle* circle_new();// 正方形类
CLASS (square)
{IMPLEMENTS (baseShape);void (*vMove) (void*);
};
extern square* square_new();#endif //_MYINTERFACE_H

myInterface.c文件

#include "myInterface.h"
#include "string.h"
#include "stdio.h" /********************圆类的实现*******************/void cinit(void*p,char*name)
{circle*pthis = (circle*)p;strcpy(pthis->baseShape.name,name);
}void cdraw(void*p)
{circle*pthis = (circle*)p;printf("%s drawing\n",pthis->baseShape.name);
}void cmove(void *p)
{circle*pthis = (circle*)p;printf("%s moving\n",pthis->baseShape.name);
}CTOR (circle)FUNCTION_SETTING(vMove,cmove);FUNCTION_SETTING(baseShape.init,cinit);FUNCTION_SETTING(baseShape.draw,cdraw);
END_CTOR/********************正方形类的实现*******************/
void sinit(void*p,char*name)
{square*pthis = (square*)p;strcpy(pthis->baseShape.name,name);
}void sdraw(void*p)
{square*pthis = (square*)p;printf("%s drawing\n",pthis->baseShape.name);
}void smove(void *p)
{square*pthis = (square*)p;printf("%s moving\n",pthis->baseShape.name);
}CTOR (square)FUNCTION_SETTING(vMove,smove);FUNCTION_SETTING(baseShape.init,sinit);FUNCTION_SETTING(baseShape.draw,sdraw);
END_CTOR

结果
在这里插入图片描述


  lw_oopc相关的文件大家可以去gitee或者是github上面找找,上面有很多示例,博主还没完全码明白。oopc相关文件的示例仓库😅😅😅



小编会持续更新的哟!欢迎大家点赞+收藏+关注!!!🤤🤤🤤

相关文章:

【UML+OOPC嵌入式C语言开发】使用C语言实现一个面向对象语言才能够实现的类

文章目录简述OOPC开发环境知识讲解函数示例类的实现示例接口实现示例&#xff08;前面两部分有点无聊&#xff0c;如果大家没兴趣看可以直接从知识讲解开始看&#xff09; 简述OOPC oopc&#xff0c;是一种轻量级的面向对象的C语言编程框架&#xff0c; LW_OOPC是Light-Weight …...

软件测试自动化Java篇【Selenium+Junit 5】

文章目录Selenium环境部署自动化测试例子常见的元素操作窗口等待浏览器的操作弹窗选择器执行脚本文件上传浏览器参数Junit 5导入依赖Junit 4 和 Junit5 注解对比断言测试顺序参数化单参数多参数动态参数测试套件指定类来运行测试用例指定包名来运行包下测试用例Selenium 为什么…...

Clip:学习笔记

Clip 文章目录Clip前言一、原理1.1 摘要1.2 引言1.3 方法1.4 实验1.4.1 zero-shot Transfer1.4.2 PROMPT ENGINEERING AND ENSEMBLING1.5 局限性二、总结前言 阅读论文&#xff1a; Learning Transferable Visual Models From Natural Language Supervision CLIP 论文逐段精读…...

STM32CubexMX与FreeRTOS学习

目录 LED与EXTI配置 基本定时器使用 软件定时器 在HAL库中实现printf 重点--记得自己添加头文件 队列实现 二值信号量实现 计数信号量实现 DMA实现 ADC配置 RTC配置 看门狗 窗口看门狗 FreeRTOS结合MX软件开发&#xff0c;基础配置直接生成&#xff0c;我们只…...

Master Slave 主从同步错误 Slave_IO_Running:NO/Slave_SQL_Running: No

Master Slave 主从同步错误 Slave_IO_Running:NO Slave_SQL_Running:Yes #在Slave库上查看状态 mysql> show slave status\G Slave_IO_Running: No Slave_SQL_Running: Yes #重启master库&#xff1a;service mysqld restart mysql> show master status; ------------…...

JavaScript函数之prototype原型和原型链

文章目录1. 原型2. 显式和隐式原型3. 原型链3.1 访问顺序4. instanceof4.1 如何判断1. 原型 函数的prototype属性 每个函数都有一个prototype属性&#xff0c;它默认指向一个Object空对象&#xff08;即&#xff1a;原型对象&#xff09;。原型对象中有一个属性constructor&a…...

从上海分时电价机制调整看转供电用户电能计费

安科瑞 耿敏花2022年12月16日&#xff0c;上海市发改委发布《关于进一步完善我市分时电价机制有关事项的通知》(沪发改价管〔2022〕50号)。通知明确上海分时电价机制&#xff0c;一般工商业及其他两部制、大工业两部制用电夏季&#xff08;7、8、9月&#xff09;和冬季&#xf…...

TypeScript类型体操:获取数组中元素对象属性的值作为新类型

title: TypeScript类型体操&#xff1a;获取数组中元素对象属性的值作为新类型 date: 2023-03-03 20:58:24 categories: TypeScript类型体操 tags: TypeScript类型体操TypeScript 首先先说获取数组中元素对象属性的值作为新类型的解决方案 使用 as const 强调不可变数组使用 …...

npm,yarn和pnpm

npm扁平的node_modules结构比如项目依赖了A 和 C&#xff0c;而 A 和 C 依赖了不同版本的 B1.0 和 B2.0&#xff0c;D也依赖B1.0, node_modules 结构如下&#xff1a;node_modules ├── A1.0.0 ├── B1.0.0 └── C1.0.0└── node_modules└── B2.0.0C依赖的B2.0因为版…...

【算法】【数组与矩阵模块】在排好序的矩阵中找数,时间复杂度O(M+N)

目录前言问题介绍解决方案代码编写java语言版本c语言版本c语言版本思考感悟写在最后前言 当前所有算法都使用测试用例运行过&#xff0c;但是不保证100%的测试用例&#xff0c;如果存在问题务必联系批评指正~ 在此感谢左大神让我对算法有了新的感悟认识&#xff01; 问题介绍 …...

【Java|基础篇】计算机中数据的存储规则

文章目录前言:1.计算机中的数据2.二进制的介绍二进制的运算规则常见的进制3.字符的存储4.汉字的存储5.图片的存储6.音频的存储总结:前言: 本篇文章只是为了科普 计算机中数据的存储规则 1.计算机中的数据 计算机的数据大致分为三类:文本数据,图片和音频 注:视频是图片和音频…...

RestTemplate使用HttpClient连接池

文章目录RestTemplate使用HttpClient连接池ClientHttpRequestFactorySimpleClientHttpRequestFactorySimpleClientHttpRequestFactory 设置超时时间HttpURLConnection的缺点HttpComponentsClientHttpRequestFactoryPoolingHttpClientConnectionManager配置连接池HttpClient总结…...

Python 操作Redis

在 Python中我们使用 redis库来操作 Redis数据库。Redis数据库的使用命令这里就不介绍了。 需要安装 redis库。检查是否安装redis&#xff1a; pip redis 如果未安装&#xff0c;使用 pip命令安装 redis。 pip install redis #安装最新版本 一、Redis连接 Redis提供两个类 Re…...

CEC2020:鱼鹰优化算法(Osprey optimization algorithm,OOA)求解CEC2020(提供MATLAB代码

一、鱼鹰优化算法简介 鱼鹰优化算法&#xff08;Osprey optimization algorithm&#xff0c;OOA&#xff09;由Mohammad Dehghani 和 Pavel Trojovsk于2023年提出&#xff0c;其模拟鱼鹰的捕食行为。 鱼鹰是鹰形目、鹗科、鹗属的仅有的一种中型猛禽。雌雄相似。体长51-64厘米…...

词对齐 - MGIZA++

文章目录关于 MGIZAgiza-py安装 MGIZA命令说明mkclsd4normhmmnormplain2sntsnt2coocsnt2coocrmpsnt2plainsymalmgizageneral parameters:No. of iterations:parameter for various heuristics in GIZA for efficient training:parameters for describing the type and amount o…...

GUI 之 Tkinter编程

GUI 图形界面&#xff0c;Tkinter 是 Python 内置的 GUI 库&#xff0c;IDLE 就是 Tkinter 设计的。 1. Tkinter 之初体验 import tkinter as tkroot tk.Tk() # 创建一个窗口root.title(窗口标题)# 添加 label 组件 theLabel tk.Label(root, text文本内容) theLabel.p…...

【软件测试】性能测试面试题都问什么?面试官想要什么?回答惊险避坑......

目录&#xff1a;导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09;前言 1、你认为不同角色关…...

后端开发基础能力以及就Java的主流开发框架介绍

前言&#xff1a;java语言开发转后端&#xff0c;必须了解后端主流的一些东西&#xff0c;共勉。 后端开发需要具备以下基础能力&#xff1a; 1.编程语言&#xff1a;熟练掌握至少一门编程语言&#xff0c;如Java、Python、Ruby、PHP、C#等。 2.数据结构和算法&#xff1a;具…...

H2数据库连接时用户密码错误:Wrong user name or password [28000-214] 28000/28000 (Help)

H2数据库连接时用户密码错误: 2023-03-03 08:25:07 database: wrong user or password; user: "SA" org.h2.message.DbException: Wrong user name or password [28000-214]出现的问题配置信息原因解决办法org.h2.message.DbException: Wrong user name or password …...

青岛诺凯达机械盛装亮相2023济南生物发酵展,3月与您相约

BIO CHINA生物发酵展&#xff0c;作为生物发酵产业一年一度行业盛会&#xff0c;由中国生物发酵产业协会主办&#xff0c;上海信世展览服务有限公司承办&#xff0c;2023第10届国际生物发酵展&#xff08;济南&#xff09;于2023年3月30-4月1日在山东国际会展中心&#xff08;济…...

【JAVA程序设计】【C00111】基于SSM的网上图书商城管理系统——有文档

基于SSM的网上图书商城管理系统——有文档项目简介项目获取开发环境项目技术运行截图项目简介 基于ssm框架开发的网上在线图书售卖商城项目&#xff0c;本项目分为三种权限&#xff1a;系统管理员、卖家、买家 管理员角色包含以下功能&#xff1a; 用户信息管理、权限管理、订…...

基于卷积神经网络CNN的三相故障识别

目录 背影 卷积神经网络CNN的原理 卷积神经网络CNN的定义 卷积神经网络CNN的神经元 卷积神经网络CNN的激活函数 卷积神经网络CNN的传递函数 卷积神经网络CNN手写体识别 基本结构 主要参数 MATALB代码 结果图 展望 背影 现在生活&#xff0c;为节能减排&#xff0c;减少电能损…...

Java工厂设计模式详解,大厂的Java抽象工厂模式分享!

我是好程序员-小源&#xff01;本期文章主要给大家分享&#xff1a;Java工厂设计模式。文中使用通俗易懂的案例&#xff0c;使你快速学习和轻松上手&#xff01;一、什么是Java抽象工厂模式1. Java抽象工厂是23种设计模式中创建型模式的一种&#xff0c;Java抽象工厂是由多个工…...

Git 企业级分支提交流程

Git 企业级分支提交流程 首先在本地分支hfdev上进行开发&#xff0c;开发后要经过测试。 如果测试通过了&#xff0c;那么久可以合并到本地分支develop&#xff0c;合并之后hfdev和development应该完全一样。 git add 文件 git commit -m ‘注释’ git checkout develop //切换…...

C/C++每日一练(20230303)

目录 1. 字符串相乘 2. 单词拆分 II 3. 串联所有单词的子串 1. 字符串相乘 给定两个以字符串形式表示的非负整数 num1 和 num2&#xff0c;返回 num1 和 num2 的乘积&#xff0c;它们的乘积也表示为字符串形式。 示例 1: 输入: num1 "2", num2 "3"…...

Python3-条件控制

Python3 条件控制 Python 条件语句是通过一条或多条语句的执行结果&#xff08;True 或者 False&#xff09;来决定执行的代码块。 可以通过下图来简单了解条件语句的执行过程: 代码执行过程&#xff1a; if 语句 Python中if语句的一般形式如下所示&#xff1a; if condi…...

KDZD地埋电缆故障测试仪

一、产品特性 ★电缆故障测试仪&#xff08;闪测仪&#xff09; &#xff08;1&#xff09;使用范围广&#xff1a;用于测量各种不同截面、不同介质的各种电力电缆、高频同轴电缆&#xff0c;市话电缆及两根以上均匀铺设的地埋电线等电缆高低阻、短路、开路、断线以及高阻泄漏…...

爆款升级!新系列南卡Neo最强旗舰杀到,业内首款无线充骨传导耳机!

中国专业骨传导耳机品牌NANK南卡于近日发布了全新南卡Neo骨传导运动耳机&#xff0c;打造一款佩戴最舒适、音质体验最好的骨传导耳机。推出第2代声学響科技技术&#xff0c;提供更优质的开放式骨传导听音体验&#xff0c;透过不一样的音质体验&#xff0c;打造更好的骨传导耳机…...

基于Spring Boot+Thymeleaf的在线投票系统

文章目录 项目介绍主要功能截图:后台登录注册个人信息展示投票数据显示首页展示对战匹配分数排行榜部分代码展示设计总结项目获取方式🍅 作者主页:Java韩立 🍅 简介:Java领域优质创作者🏆、 简历模板、学习资料、面试题库【关注我,都给你】 🍅文末获取源码联系🍅…...

【每日一题Day135】LC1487保证文件名唯一 | 哈希表

保证文件名唯一【LC1487】 给你一个长度为 n 的字符串数组 names 。你将会在文件系统中创建 n 个文件夹&#xff1a;在第 i 分钟&#xff0c;新建名为 names[i] 的文件夹。 由于两个文件 不能 共享相同的文件名&#xff0c;因此如果新建文件夹使用的文件名已经被占用&#xff0…...

备案变更网站/安卓手机优化软件排名

记录一下自己安装VS2010与Opencv的配置过程&#xff0c;方便以后查看使用&#xff0c;开发环境的搭建&#xff1a; 1. 下载安装Opencv&#xff0c;去官网http://opencv.org/即可下载最新版本的Opencv&#xff0c;此处用的是Opencv 2.4.10 安装时傻瓜式的&#xff0c;最新版本的…...

视频上传网站如何做/谷歌商店paypal下载官网

切换到第一个文本终端。在Linux下你可以有多达六个不同的终端。这个命令的意思是&#xff1a;“同时按住键和键&#xff0c;然后按键&#xff0c;再释放所有的键”。(n1..6)切换到第n个文本终端。(你也可以使用不是很经常用到的命令chvt n来实现&#xff0c;n指的是第n个文本终…...

wordpress 后台设置/万网官网域名查询

2018年南开大学物理保研夏令营通知导读&#xff1a;南开大学物理2018年保研夏令营通知已经公布&#xff0c;宣讲及面试活动时间为4月27日(周四)上午8:00-12:00。具体内容请看如下信息&#xff0c;想了解更多相关信息请持续关注我们应届毕业生考试网!为方便广大2018届优秀应届本…...

单页面网站带后台/龙岩网站推广

Java基础&#xff08;对象线程字符接口变量异常方法&#xff09; 面向对象和面向过程的区别&#xff1f;Java 语言有哪些特点&#xff1f;关于 JVM JDK 和 JRE 最详细通俗的解答Oracle JDK 和 OpenJDK 的对比Java 和 C的区别&#xff1f;什么是 Java 程序的主类&#xff1f;应…...

素材中国免费素材网官网/百度seo和谷歌seo有什么区别

文章目录1. Spring Boot1.1 什么是Spring Boot&#xff1f;1.2 SpringBoot 官方的一些解释2. 微服务架构2.1 单体应用架构2.2 微服务架构2.3 分布式要解决的问题3. 搭建第一个SpringBoot程序3.1 在官方下载一个SpringBoot程序3.2 在IDEA中&#xff0c;创建SpringBoot程序(推荐)…...

做网站开发的女生多吗/seo排名快速上升

热身&#xff1a;轴承故障检测训练赛 任务 轴承有3种故障&#xff1a;外圈故障&#xff0c;内圈故障&#xff0c;滚珠故障&#xff0c;外加正常的工作状态。如表1所示&#xff0c;结合轴承的3种直径&#xff08;直径1,直径2,直径3&#xff09;&#xff0c;轴承的工作状态有10…...