c语言实现this指针效果
概要
由于目前在做一个比较复杂的嵌入式项目,想要借此提升一下代码的结构设计能力,所以想要以面向对象的思想来完成这个项目,即把每个板载外设资源视为一个对象,采用msp+bsp的模式,对每个bsp外设实现对象化处理,现有方案需要手动传入对象引用,调用方法时比较麻烦,所以考虑简化调用方式。
面向对象实现思路
现有方案
对象就是具有属性与方法的集合体,以LED举例,它的属性就是端口,引脚,亮使能标志等,方法就是亮,灭。
了解到现有的c语言面向对象实现方法都需要手动传入对象的引用,如下这种方式:
typedef struct _LED_TYPEDEF{
//属性
struct _Privated_Attr{
GPIO_InitTypeDef GPIO_Body;
GPIO_TypeDef *GPIOx;
GPIO_PinState ENbit;
} Privated_Attr;
//方法
void (*LightUp)(struct _LED_TYPEDEF *);
void (*LightOff)(struct _LED_TYPEDEF *);
}LED_TypeDef;
上面的结构体中有一个嵌入的结构体变量,主要用途就是类似私有变量,类外不可直接访问的目的,也是出于属性只由方法操作,这样可以对属性值的合理性做出一定限制与约束,然后方法的参数必须加入对象的引用,也就是传入对象地址。
此时调用方法为:
//实例化对象
LED_TypeDef BSP_LED1;
LED_TypeDef BSP_LED2;
//对象方法使用
BSP_LED1.LightUp(&BSP_LED1); //led1亮
BSP_LED2.LightOff(&BSP_LED2);//led2灭
这种方式比较麻烦,所以有必要引入c++的this指针方式。
this方案
目的:为了简写对象方法的调用模式。
所谓的this指针可以简单理解为编译器帮我们把对象引用传递到方法中了。
单一bsp方案
此单一bsp意为板子上只有这一个外设,所以这个bsp对象只需要一个this指针,以uart举例
typedef struct _UART_OBJ_TYPEDEF{
//属性
struct _PrivateAttr{
uint16_t Buf_Cnt;
UART_HandleTypeDef UARTxHandler;
}PrivateAttr;
uint8_t Is_RX_OV;
uint8_t Is_RX_OK;
uint8_t RX_Buf[UART_RX_MAX_SIZE];
//方法
void (*SendChar)(struct _UART_OBJ_TYPEDEF *,uint8_t chr);
void (*SendStr)(struct _UART_OBJ_TYPEDEF *,uint8_t *str);
void (*ClearBuf)(void);
void (*ClearFlag)(void);
void (*BufAppend)(uint8_t byte);
uint16_t (*GetBufLength)(void);
}UART_Obj_TypeDef;
可以看到方法中不再需要手动传入对象引用了。
UART_Obj_TypeDef UART_Debug_Obj; //实例化对象
static UART_Obj_TypeDef *mthis = &UART_Debug_Obj; //this指针实现对象引用
这样就利用static文件的作用域实现为每个bsp对象实现一个this指针效果。
//将数据放入缓冲区
UART_Debug_Obj.BufAppend(res);
//清空缓冲区
UART_Debug_Obj.ClearBuf();
多个同类bsp方案
//bsp对象的this数组偏移量
#define BSP_LED1_OFFSET 0
#define BSP_LED2_OFFSET 1
//间接改变this的指向
#define BSP_LED1 (this_ledx = BSP_LED1_OFFSET);_BSP_LED1
#define BSP_LED2 (this_ledx = BSP_LED2_OFFSET);_BSP_LED2
struct _LED_TYPEDEF;
typedef struct _LED_TYPEDEF{
struct _Privated_Attr{
GPIO_InitTypeDef GPIO_Body;
GPIO_TypeDef *GPIOx;
GPIO_PinState ENbit;
} Privated_Attr;
void (*LightUp)(void);
void (*LightOff)(void);
}LED_TypeDef;
使用宏定义的方式间接改变this的指向
//实例化2个同类对象
LED_TypeDef _BSP_LED1;
LED_TypeDef _BSP_LED2;
//this指针与this数组
static LED_TypeDef* This_Arr[LED_NUM] = {&_BSP_LED1,&_BSP_LED2};
static LED_TypeDef* mthis;
//this指向偏移量(因为外面要用,所以名字不要冲突,最好和bsp对象相关)
uint8_t this_ledx = BSP_LED1_OFFSET;
//方法定义
void LightUp(){
mthis = This_Arr[this_ledx]; //通过this指针偏移来确定使用哪个对象
HAL_GPIO_WritePin(mthis->Privated_Attr.GPIOx,\
mthis->Privated_Attr.GPIO_Body.Pin,\
mthis->Privated_Attr.ENbit);
}
总结
基于面向对象的思想对于代码的结构和可读性上都有一定的利处,特别在裸机编写过程中,由于不受系统的干预,对于思路与框架的设计都清晰起来,目前还在不断改善中,希望这种方式可以很好的在项目中使用。
c语言实现this指针效果的更多相关文章
- C语言之漫谈指针(下)
C语言之漫谈指针(下) 在上节我们讲到了一些关于指针的基础知识: 详见:C语言之漫谈指针(上) 本节大纲: 零.小tips 一.字符指针 二.指针数组与数组指针 三.数组传参与指针传参 四.函数指针及 ...
- Swift3.0语言教程使用指针创建和初始化字符串
Swift3.0语言教程使用指针创建和初始化字符串 Swift3.0语言教程使用指针创建和初始化字符串苹果的Swift团队花了不少功夫来支持C的一些基础特性.C语言中为我们提供了指针,Swift也不例 ...
- C语言中的指针数组
C语言中的指针数组是什么,像 char *a[]={"ddd","dsidd","lll"}; 这里讲一下注意如果我们使用了a也就是首元素的 ...
- 【ZZ】C 语言中的指针和内存泄漏 & 编写高效的C程序与C代码优化
C 语言中的指针和内存泄漏 http://www.ibm.com/developerworks/cn/aix/library/au-toughgame/ 本文讨论了几种在使用动态内存分配时可以避免的陷 ...
- GO语言中的指针
http://www.tizgrape.com/?p=100 Go语言中的指针语法和C++一脉相承,都是用*作为符号,虽然语法上接近,但是实际差异不小. Go使用var定义变量: var v6 *in ...
- 由链表初始化看C语言的二级指针
先来看C语言创建链表.插入节点和遍历链表的一段代码: #include <stdio.h> #include <stdlib.h> typedef int ElemType; ...
- C语言 > 数组和指针
C语言 数组和指针 const: 关于指针和const需要注意一些规则.首先,把const数据或非const数据的地址初始化为指向const的指针或为其赋值是合法的. 然而,只能把非const数据的地 ...
- EF+LINQ事物处理 C# 使用NLog记录日志入门操作 ASP.NET MVC多语言 仿微软网站效果(转) 详解C#特性和反射(一) c# API接受图片文件以Base64格式上传图片 .NET读取json数据并绑定到对象
EF+LINQ事物处理 在使用EF的情况下,怎么进行事务的处理,来减少数据操作时的失误,比如重复插入数据等等这些问题,这都是经常会遇到的一些问题 但是如果是我有多个站点,然后存在同类型的角色去操作 ...
- C语言结构体指针的引用问题
在写栈的一个应用时遇见这样的一个问题 SqStack s; s->base = (int*)malloc(sizeof(int)*10); 通过这样一个代码引用的时候,会导致程序出现异常 经过一 ...
- Go语言基础之指针
区别于C/C++中的指针,Go语言中的指针不能进行偏移和运算,是安全指针. 要搞明白Go语言中的指针需要先知道3个概念:指针地址.指针类型和指针取值. Go语言中的指针 Go语言中的函数传参都是值拷贝 ...
随机推荐
- 独奏者2 序章的wp
0x01 0ctf_2017_babyheap 2023.7.24 国防科技大学 合肥 本题除了fastbin attack,最重要的是伪造fakechunk,使得存放chunk的指针有两个指向同一个 ...
- 【Windows】KMS 激活命令记录
目录 KMS 服务器激活 Office.Visio 推荐使用 office tool plus 部署并配置 KMS 激活 什么是 KMS? KMS 正版与否的区别 总结 KMS 服务器激活 利用 KM ...
- GaussDB技术解读系列:高安全之密态等值
本文分享自华为云社区< DTCC 2023专家解读 | GaussDB技术解读系列:高安全之密态等值>,作者:GaussDB 数据库. 近日,在第14届中国数据库技术大会(DTCC2023 ...
- 非全自研可视化表达引擎-RuleLinK
说在前面 工作中经常会遇到这样的场景: 帮忙把小贝拉门店 商品金额在5w以内,产康订单最多95折. 帮忙把圣贝拉门店 开业时间在6个月内,折扣低于7折要发起审批 帮忙把宁波太平洋店设置独立合同模板 帮 ...
- CodeForces 1367E Necklace Assembly
题意 给定一个字符串\(s\),长度为\(n\),一根项链为一个环,定义一根项链为\(k-beautiful\),则该项链顺时针转\(k\)下后与原项链相等,给出\(k\),请构造一根最长的\(k-b ...
- Java下载多个网络文件并打成压缩包
需求:浏览器访问后台的http地址后,后台将多个网络文件打成压缩包返回给浏览器,用户可以通过浏览器直接下载压缩包. 实现: 根据文件链接把文件下载下来并且转成字节码 ,代码: package com ...
- textarea自动适应高度
textarea自动适应高度,兼容IE/Firefox.chrome 代码:<textarea name="textarea" id="textarea" ...
- 请大家一定不要像我们公司这样打印log日志
前言 最近接手了公司另一个项目,熟悉业务和代码苦不堪言. 我接手一个新项目,有个习惯,就是看结构,看数据库,搜代码. 其中搜代码是我个人这些年不知不觉形成的癖好,我下面给大家展示下这个小癖好. 正文 ...
- linux下查找文件中某字符串出现的行以及该行前后n行
linux下查找文件中某字符串出现的行以及该行前后n行 查找指定字符串的前后n行 grep -A 100 -B 100 "要查找的字符串" 被查找的文件 -A after 后面 - ...
- Vue之键盘事件
1.使用keydown触发事件 <!DOCTYPE html> <html lang="en"> <head> <meta charset ...