面向对象设计思想-C语言
面向对象的三个特征:封装,继承,多态。但是C语言不是面向对象编程语言,所以需要借助一些技巧来实现这三个特征:
(1)C语言没有成员函数,struct只能封装数据,不能封装方法,可以在struct里使用函数指针;
(2)C语言不支持继承,可以在一个struct里包含另一个struct;
(3)C语言也没有虚函数,实现多态就更麻烦了,我不会。举个例子:现在有Point结构体定义如下:
struct Point{float x; float y;
};
如果想从Point派生出Circle,可以这么写:
struct Circle{ struct Point o; //圆心 float r; //半径};
struct Circle C;struct Point *pPoint = (struct Point*)(&C);
此时如果将Circle类型的指针强制换换成Point类型指针,因为内存是顺序连续的,所以没问题,pPoint->x访问的是C.o.x,pPoint->y访问的是C.o.y.也就是说在需要基类指针的地方可以传入派生类的指针。
但是如果将o和r的顺序换一下就错了。
struct Circle{ float r; //半径 struct Point o; //圆心};
struct Circle C;struct Point *pPoint = (struct Point*)(&C);//这么转会出问题
简单来说就是如果想使用C语言的继承,那么基类对象一定要写在派生类的最前面!但是对C语言编程而言,不建议使用继承和多态,使用封装就可以了。对封装的理解可以退化为:不直接访问结构体的成员变量而是通过函数去访问(C语言没有private属性,直接访问成员变量总是可以的,但是不建议这么做);此外C语言结构体没有this指针,所以使用函数指针封装方法也用的比较少,更多的是提供一些全局函数,将结构体指针作为参数传进去操作。
假设有个Moubus数据包的结构体:
#define PACK_SIZE 256
struct ModbusPack{ uint8_t data[PACK_SIZE]; uint8_t len;};
还有和它对应的操作函数:
void Modbus_init(struct ModbusPack *pThis);
void Modbus_append(struct ModbusPack *pThis,uint8_t v);
void Modbus_appends(struct ModbusPack *pThis,uint8_t *vs,uint8_t len);
uint8_t Modbus_len(struct ModbusPack *pThis);
void Modbus_append_crc(struct ModbusPack *pThis);
uint8_t Modbus_check(struct ModbusPack *pThis);
void Modbus_init_query(struct ModbusPack *pThis,uint8_t addr,uint8_t fc,uint16_t regbase,uint16_t regNum);
void Modbus_print(struct ModbusPack *pThis);
对于Modbus_len这个函数的实现如下:
uint8_t Modbus_len(struct ModbusPack *pThis) {//省略对指针是否为空的判断 return pThis->len;
}
看起来比直接访问成员变量复杂,好处在于当修改了ModbusPack的实现,将len改为m_len,则只需要修改Modbus_xxx函数就行了,不影响其他地方对这个函数的调用,因为调用的地方只依赖于这个函数的名字,而不需要知道相应结构体的具体实现。
struct ModbusPack{ uint8_t m_data[PACK_SIZE]; uint8_t m_len;};
uint8_t Modbus_len(struct ModbusPack *pThis) { //省略对指针是否为空的判断 return pThis->m_len;}
简单的使用例子如下:
#include "modbus.h"
int main(){ struct ModbusPack pack; Modbus_init(&pack);//C语言没有构造函数,通过初始化函数初始化对象 Modbus_init_query(&pack,0x01,0x03,0x0000,0x0002); Modbus_print(&pack); return 0;}
运行结果:
友情提示:找对象虽易,面向对象不易,且行且珍惜。
声明:
本文于网络整理,版权归原作者所有,如来源信息有误或侵犯权益,请联系我们删除或授权事宜。
面向对象设计思想-C语言相关推荐
- 【Java设计模式 面向对象设计思想】一 再谈面向对象和封装、抽象、继承、多态四大特性
回看最初的目标:[Java设计模式 学习目标及大纲]高质量代码的标准及实现路径在这篇Blog里我们明确了什么是高质量的代码:易维护.易读.易扩展.灵活.简洁.可复用.可测试,也知道高质量代码的达成路径 ...
- 从面向对象设计思想出发理解Spring AOP编程
都说AOP是OOP(面向对象)的继承与延续,我觉得理解AOP还是得从OOP出发,经历从暴露问题到解决问题的过程. 目录 一. 面向对象设计思想(OOP) (1)概述 1. POP编程 2. OOP的优 ...
- 面向对象设计思想总结及代码
一.运行面向对象思想实现 超级简单需求:老张开车去东北 目的:体会面向对象思想 """面向对象设计思想(旧)需求:老张开车去东北变化:增加飞机.汽车....封装:划分类 ...
- 面向对象设计思想_重要_2
Java与面向对象 对象是Java程序的核心,在Java程序中"万事万物皆对象". 对象可以看成是静态属性(成员变量)和动态属性(方法)的封装体. 类是用来创建同一类型的对象的&q ...
- 面向对象设计思想-基本概念
面向对象最需要的是 抽象的能力. 这个能力需要通过大量编写代码和思考系统结构来获得.类与类的关系,包与包的关系,项目与项目的关系. 架构师的抽象能力要更深一层,代码结构,数据结构,文件结构,项目结构, ...
- 【Java设计模式 面向对象设计思想】五 多用组合少用继承编程
我们经常会听到说多用组合少用继承,但是拜托,继承是面向对象四大特性之一啊,为什么地位反不如组合了呢,为什么不推荐使用继承?组合相比继承有哪些优势?如何判断该用组合还是继承?围绕这三个问题进行以下讨论 ...
- 【嵌入式Linux】嵌入式Linux驱动开发基础知识之LED驱动框架--面向对象、分层设计思想
文章目录 前言 1.LED驱动程序框架 1.1.对于LED驱动,我们想要什么样的接口? 1.2.LED驱动要怎么写,才能支持多个板子?分层写 1.3.程序分析 驱动程序 应用程序 Makefile 1 ...
- 面向对象设计六大基本原则
目录 单一职责原则 开闭原则 里氏替换原则 依赖倒置原则 接口隔离原则 迪米特原则 单一职责原则 本篇开始介绍面向对象设计思想 单一职责原则,Single Responsibility Princip ...
- Silverlight游戏设计(Game Design):(五)面向对象的思想塑造游戏对象
传说,面向对象的开发模式最初是因为程序员偷懒而不小心诞生的.发展至今,人们从最初的热忠于讨论某某语言是否足够面向对象到现在开始更广泛的关注面向对象的思想而不是具体内容.面向对象的思想其实并不深奥,它存 ...
最新文章
- chrome使用技巧(看了定不让你失望)
- HTML5学习笔记简明版(10):过时的元素和属性
- python函数结构_Python函数基础
- 计算机英语仲裁合词,仲裁 arbitration 法律英语常用词
- 【Android】关于Android控件EditText的属性InputType的一些经验
- tomcat启动时,报java.io.EOFException
- tcp长连接和保活时间
- LearnOpenGL之OpenGL特性
- 【R语言实用技巧】类别变量的顺序自定义设置
- SPSS时间序列分析
- 搞写商业计划书的要点
- 小虾米的求助Massage
- bfs之走地图(迷宫)
- SRM 543 Div2
- 抖音橱窗等级被降低了是什么原因造成的?怎么办?
- python2 unicode转换中文
- php数据类型int大小,数据类型:int
- 关于“远程计算机或设备不接受连接”解决方法
- ASP.NET的SEO:基础知识 (1)
- 手机和Linux蓝牙通信,linux 用蓝牙和手机通信
热门文章
- jpa 分页 排序 过滤_使用JPA标准@ViewScoped通过分页,过滤和排序进行Primefaces DataTable延迟加载...
- 使用混合多云每个人都应避免的3个陷阱(第3部分)
- Packt发行的$ 5 Java编程书籍:精通Java 9,Java 9 High Performance
- Java EE与Java SE:Oracle是否放弃了企业软件?
- 介绍“又一个” Cloud Foundry Gradle插件
- 纯Java中的Functor和Monad示例
- 教程:正确的SLF4J日志记录用法以及如何检查它
- 引入ReactiveInflux:用于Scala和Java的无阻塞InfluxDB驱动程序,支持Apache Spark
- 带有Gluon Ignite和Dagger的JavaFX中的依赖注入
- 使用Apache Drill REST API通过Node构建ASCII仪表板