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

使用C语言实现面向对象程序设计

学过c语言的人都直到c语言学习语法简单,但精通起来比较难,难点在于c语言太“低级”,它面向的是机器的一个执行过程,不像C++、java这种高级语言,在语法层级就支持面向对象的抽象。所以往往初学者在使用c语言编程时,稍微遇到复杂一点的功能,就会出现各种全局变量,标志位满天飞的情况,代码维护性和阅读性变得很差,过个一两年再去阅读自己以前写的代码,遇到没写注释的全局变量,可能都得靠猜。

但其实这也是c语言区别于其他语言最优秀的地方,因为语法简单,没有语法上的各种约束和限制,它是最容易上手的语言,其他面向对象的语言,你首先得有一个对事物的抽象能力,才能把程序的结构设计好。同时它具有别的编程语言不能比拟的最优秀的执行效率,因此在资源受限的场景下,比如嵌入式,单片机等,c语言是一个不错的选择。但并不意味着c语言只能处理这种偏“底层”的应用场景,使用c语言同样能实现面向对象的程序设计。并且它在某些方面还优于其他高级语言。下面结合我的理解讲一讲如何使用c语言实现面向对象的程序设计。

面向对象核心特性

1. 封装

通过结构体与函数指针捆绑数据与操作,例如封装一个对象,用于描述系统电源特性,包括电压、电流、充放电状态等,同时定义这个对象的操作方法

电源 {

电压,

电流,

电源状态,

剩余电量,

操作方法:

获取电压;

获取电流;

获取电源状态;

获取剩余电量;

设置电源状态;

}

那么使用c语言如何来实现呢?

我们可以在结构体中定义对象的属性,然后使用函数指针定义这个对象的操作方法,如下:

power.h头文件定义如下:

#ifndef POWER_H #define POWER_H #include <stdlib.h> #include <stdint.h> #include <stdbool.h> #include <string.h> #define GET_POWER(obj) ((Power *)obj) // 类声明 typedef struct _Power Power; typedef struct _PowerFun PowerFun; // 类成员函数结构 struct _PowerFun { void (*destroy)(Power* self); uint16_t (*getVoltage)(Power* self);//获取电压; uint16_t (*getCurrent)(Power* self);//获取电流; uint16_t (*getPowerState)(Power* self);//获取电源状态; uint16_t (*getPowerLevel)(Power* self);//获取剩余电量; void (*setPowerState)(Power* self, uint8_t state);//设置电源状态; }; // 类结构 struct _Power { const PowerFun* fun; // TODO: 添加数据成员 uint16_t voltage; //电压, uint16_t current; //电流, uint16_t power_state;//电源状态, uint16_t power_level;//剩余电量, }; // 构造函数声明 Power* power_create(); void power_init(Power* self); // 析构函数声明 void power_deinit(Power* self); #endif // POWER_H

power.c具体实现如下:

#include "power.h" #include <stdio.h> static uint16_t power_getCurrent(Power* self); static uint16_t power_getPowerState(Power* self); static uint16_t power_getPowerLevel(Power* self); static void power_setPowerState(Power* self, uint8_t state); static uint16_t power_getVoltage(Power* self); // 析构函数声明 static void power_destroy(Power* self); // TODO: 初始化数据成员 static const PowerFun power_fun = { .destroy = power_destroy, .getVoltage = power_getVoltage, .getCurrent = power_getCurrent, .getPowerState = power_getPowerState, .getPowerLevel = power_getPowerLevel, .setPowerState = power_setPowerState, }; // 构造函数实现 Power* power_create() { Power* obj = (Power*)malloc(sizeof(Power)); if (obj) { memset(obj, 0, sizeof(Power)); power_init(obj); } return obj; } void power_init(Power* self) { self->fun = &(power_fun); // TODO: 初始化数据成员 } void power_deinit(Power* self) { // TODO: 数据成员申请资源释放 } // 析构函数实现 static void power_destroy(Power* self) { if (self != NULL) { power_deinit(self); free(self); } } // getVoltage method static uint16_t power_getVoltage(Power* self) { if (self != NULL) { return self->voltage; } return 0; } // getCurrent method static uint16_t power_getCurrent(Power* self) { if (self != NULL) { return self->current; } return 0; } // getPowerState method static uint16_t power_getPowerState(Power* self) { if (self != NULL) { return self->power_state; } return 0; } // getPowerLevel method static uint16_t power_getPowerLevel(Power* self) { if (self != NULL) { return self->power_level; } return 0; } // setPowerState method static void power_setPowerState(Power* self, uint8_t state) { if (self != NULL) { self->power_state = state; } }

使用方法很简单

Power* systempower = power_create(); systempower->fun->getVoltage(systempower);//获取电压; systempower->fun->getCurrent(systempower);//获取电流; systempower->fun->getPowerState(systempower);//获取电源状态; systempower->fun->getPowerLevel(systempower);//获取剩余电量; systempower->fun->setPowerState(systempower, 11);//设置电源状态;

2. 继承

所谓继承,就是基于一个已有的类(父类)来创建一个新的类(子类)。子类会自动获得父类的属性和方法,并且可以在此基础上进行扩展,增加自己特有的属性和方法,或者修改父类的方法。

那么在c语言中如何实现继承呢?我们可以通过结构体嵌套实现这种继承的层次关系

回到上面的例子,再次定义一个对象chargepower继承自上面定义的power对象,这个对象新增充电和放电操作方法,并且新增了充电电流、电压和放电电流、电压、充满剩余时间等属性。

充放电电源:继承电源 {

充电电压,

充电电流,

放电电压,

放电电流,

充满剩余时间,

操作方法:

充电;

放电;

}

chargepower.h定义如下

#ifndef CHARGEPOWER_H #define CHARGEPOWER_H #include <stdint.h> #include <stdbool.h> #include "Power.h" #define GET_CHARGEPOWER_VTABLE(obj) GET_POWER_VTABLE(obj) //(*(ChargepowerVTable **)obj) #define GET_CHARGEPOWER(obj) ((Chargepower *)obj) // 派生类声明 typedef struct _Chargepower Chargepower; typedef struct _ChargepowerFun ChargepowerFun; // 类成员函数结构 struct _ChargepowerFun { void (*destroy)(Chargepower* self); void (*charge)(Chargepower* self);//充电 void (*discharge)(Chargepower* self);//放电 }; struct _Chargepower { Power base; // 基类作为第一个成员 const ChargepowerFun* fun; // TODO: 添加派生类特有的数据成员 uint16_t charge_voltage; //充电电压, uint16_t charge_current; //充电电流, uint16_t discharge_voltage;//放电电压, uint16_t discharge_current;//放电电流, uint16_t charge_time;//充电剩余时间 }; // 构造函数声明 Chargepower* chargepower_create(); void chargepower_init(Chargepower* self); // 析构函数声明 void chargepower_deinit(Chargepower* self); #endif // CHARGEPOWER_H

chargepower.c定义如下:

#include "chargepower.h" #include <stdio.h> #include <stdlib.h> static void chargepower_discharge(Chargepower* self); static void chargepower_charge(Chargepower* self); // 析构函数声明 static void chargepower_destroy(Chargepower* self); // TODO: 初始化数据成员 static const ChargepowerFun chargepower_fun = { .destroy = chargepower_destroy, .charge = chargepower_charge, .discharge = chargepower_discharge, }; // 构造函数实现 Chargepower* chargepower_create() { Chargepower* obj = (Chargepower*)malloc(sizeof(Chargepower)); if (obj) { memset(obj, 0, sizeof(Chargepower)); chargepower_init(obj); } return obj; } void chargepower_init(Chargepower* self) { // 初始化基类部分 power_init(&self->base); self->fun = &(chargepower_fun); // TODO: 初始化派生类特有成员 } void chargepower_deinit(Chargepower* self) { power_deinit(GET_POWER(self)); // TODO: 数据成员申请资源释放 } // 析构函数实现 static void chargepower_destroy(Chargepower* self) { if (self != NULL) { chargepower_deinit(self); free(self); } } // charge method static void chargepower_charge(Chargepower* self) { // TODO: add charge method } // discharge method static void chargepower_discharge(Chargepower* self) { // TODO: add discharge method }

如何使用chargepower对象中的父类和自身的方法呢?

使用下面的方式即可:

Chargepower *chargepower = chargepower_create(); //调用自身方法 chargepower->fun->charge(chargepower); //充电 chargepower->fun->discharge(chargepower);//放电 //调用父类方法 GET_POWER(chargepower)->fun->getVoltage(GET_POWER(chargepower));//获取电压; GET_POWER(chargepower)->fun->getCurrent(GET_POWER(chargepower));//获取电流; GET_POWER(chargepower)->fun->getPowerState(GET_POWER(chargepower));//获取电源状态; GET_POWER(chargepower)->fun->getPowerLevel(GET_POWER(chargepower));//获取剩余电量; GET_POWER(chargepower)->fun->setPowerState(GET_POWER(chargepower), 12);//设置电源状态;

3. 多态

多态的字面意思是"多种形态"。在面向对象编程中,它指的是:同一个行为(方法)在不同的对象上会表现出不同的实现方式。

简单来说就是:使用统一的接口来操作不同类型的对象,而这些对象会根据自己的特性做出不同的响应。

那么在c语言中如何来实现多态呢?

我们可以利用函数指针,动态绑定不同的操作函数来实现多态,例如,可以在定义对象的时候,定义一个虚函数表这个虚函数表指针可以由继承的对象赋值,不同的继承对象可以赋值不同操作函数,从而实现多态

虚函数表{

虚函数指针;

}

电源 {

虚函数表,

电压,

电流,

电源状态,

剩余电量,

操作方法:

获取电压;

获取电流;

获取电源状态;

获取剩余电量;

设置电源状态;

}

示例代码,定义virtualpower.h如下:

#ifndef VIRTUALPOWER_H #define VIRTUALPOWER_H #include <stdlib.h> #include <stdint.h> #include <stdbool.h> #include <string.h> #define GET_VIRTUALPOWER_VTABLE(obj) (*(VirtualpowerVTable **)obj) #define getMaxCurrent_override(func_name) static uint16_t func_name(Virtualpower* self) #define def_getMaxCurrent(obj) (GET_VIRTUALPOWER_VTABLE(obj)->getMaxCurrent) #define virtual_getMaxCurrent(obj, ...) def_getMaxCurrent(obj)(obj, ##__VA_ARGS__) #define GET_VIRTUALPOWER(obj) ((Virtualpower *)obj) // 类声明 typedef struct _Virtualpower Virtualpower; typedef struct _VirtualpowerFun VirtualpowerFun; typedef struct _VirtualpowerVTable VirtualpowerVTable; // 虚函数表结构 typedef struct _VirtualpowerVTable { // TODO : 添加其他虚函数 uint16_t (*getMaxCurrent)(Virtualpower* self);//虚函数,由继承类来实现定义 }; // 类成员函数结构 struct _VirtualpowerFun { void (*destroy)(Virtualpower* self); uint16_t (*getVoltage)(Virtualpower* self); uint16_t (*getCurrent)(Virtualpower* self); uint16_t (*getPowerState)(Virtualpower* self); uint16_t (*getPowerLevel)(Virtualpower* self); void (*setPowerState)(Virtualpower* self, uint8_t state); }; // 类结构 struct _Virtualpower { VirtualpowerVTable* vtable; const VirtualpowerFun* fun; // TODO: 添加数据成员 uint16_t voltage; //电压, uint16_t current; //电流, uint16_t power_state;//电源状态, uint16_t power_level;//剩余电量, }; // 构造函数声明 Virtualpower* virtualpower_create(); void virtualpower_init(Virtualpower* self); // 析构函数声明 void virtualpower_deinit(Virtualpower* self); #endif // VIRTUALPOWER_H

定义virtualpower.c如下:

#include "virtualpower.h" #include <stdio.h> static uint16_t virtualpower_getVoltage(Virtualpower* self); static uint16_t virtualpower_getCurrent(Virtualpower* self); static uint16_t virtualpower_getPowerState(Virtualpower* self); static uint16_t virtualpower_getPowerLevel(Virtualpower* self); static void virtualpower_setPowerState(Virtualpower* self, uint8_t state); // 析构函数声明 static void virtualpower_destroy(Virtualpower* self); // TODO: 初始化数据成员 static const VirtualpowerFun virtualpower_fun = { .destroy = virtualpower_destroy, .getVoltage = virtualpower_getVoltage, .getCurrent = virtualpower_getCurrent, .getPowerState = virtualpower_getPowerState, .getPowerLevel = virtualpower_getPowerLevel, .setPowerState = virtualpower_setPowerState, }; // 构造函数实现 Virtualpower* virtualpower_create() { Virtualpower* obj = (Virtualpower*)malloc(sizeof(Virtualpower)); if (obj) { memset(obj, 0, sizeof(Virtualpower)); virtualpower_init(obj); } return obj; } void virtualpower_init(Virtualpower* self) { if (self->vtable == NULL) { self->vtable = (VirtualpowerVTable *) malloc(sizeof(VirtualpowerVTable)); memset(self->vtable , 0, sizeof(VirtualpowerVTable)); } self->fun = &(virtualpower_fun); // TODO: 初始化数据成员 } void virtualpower_deinit(Virtualpower* self) { if (self->vtable != NULL) { free(self->vtable); self->vtable = NULL; } // TODO: 数据成员申请资源释放 } // 析构函数实现 static void virtualpower_destroy(Virtualpower* self) { if (self != NULL) { virtualpower_deinit(self); free(self); } } // getVoltage method static uint16_t virtualpower_getVoltage(Virtualpower* self) { // TODO: add getVoltage method return 0; } // getCurrent method static uint16_t virtualpower_getCurrent(Virtualpower* self) { // TODO: add getCurrent method return 0; } // getPowerState method static uint16_t virtualpower_getPowerState(Virtualpower* self) { // TODO: add getPowerState method return 0; } // getPowerLevel method static uint16_t virtualpower_getPowerLevel(Virtualpower* self) { // TODO: add getPowerLevel method return 0; } // setPowerState method static void virtualpower_setPowerState(Virtualpower* self, uint8_t state) { // TODO: add setPowerState method }

那么当有子类继承Virtualpower这个父类时,可以实现这个虚函数

GET_VIRTUALPOWER_VTABLE(obj)->getMaxCurrent = xxxx

例如定义sonpower子类,继承自virtualpower

sonpower.h实现

#ifndef SONPOWER_H #define SONPOWER_H #include <stdint.h> #include <stdbool.h> #include "Virtualpower.h" #define GET_SONPOWER_VTABLE(obj) GET_VIRTUALPOWER_VTABLE(obj) //(*(SonpowerVTable **)obj) #define GET_SONPOWER(obj) ((Sonpower *)obj) // 派生类声明 typedef struct _Sonpower Sonpower; typedef struct _SonpowerFun SonpowerFun; // 类成员函数结构 struct _SonpowerFun { void (*destroy)(Sonpower* self); }; struct _Sonpower { Virtualpower base; // 基类作为第一个成员 const SonpowerFun* fun; // TODO: 添加派生类特有的数据成员 }; // 构造函数声明 Sonpower* sonpower_create(); void sonpower_init(Sonpower* self); // 析构函数声明 void sonpower_deinit(Sonpower* self); #endif // SONPOWER_H

sonpower.c实现

#include "sonpower.h" #include <stdio.h> #include <stdlib.h> getMaxCurrent_override(sonpower_getMaxCurrent_impl); // 析构函数声明 static void sonpower_destroy(Sonpower* self); // TODO: 初始化数据成员 static const SonpowerFun sonpower_fun = { .destroy = sonpower_destroy, }; // 构造函数实现 Sonpower* sonpower_create() { Sonpower* obj = (Sonpower*)malloc(sizeof(Sonpower)); if (obj) { memset(obj, 0, sizeof(Sonpower)); sonpower_init(obj); } return obj; } void sonpower_init(Sonpower* self) { // 初始化基类部分 virtualpower_init(&self->base); self->fun = &(sonpower_fun); // TODO: 初始化派生类特有成员 def_getMaxCurrent(self) = sonpower_getMaxCurrent_impl; } void sonpower_deinit(Sonpower* self) { virtualpower_deinit(GET_VIRTUALPOWER(self)); // TODO: 数据成员申请资源释放 } // 析构函数实现 static void sonpower_destroy(Sonpower* self) { if (self != NULL) { sonpower_deinit(self); free(self); } } // getMaxCurrent method getMaxCurrent_override(sonpower_getMaxCurrent_impl) { // TODO: add getMaxCurrent method Sonpower *sonpower = (Sonpower *)self; //params return 0; }

如何使用这个虚函数呢?
也很简单

Sonpower *sonpower = sonpower_create(); uint16_t maxcurrent = virtual_getMaxCurrent(GET_VIRTUALPOWER(systempower));

通过上面给出的例子,可以实现在c语言下使用面向对象编程。但是看起来代码比较繁杂,很多代码看起来都是一样的模式,能不能做一个插件呢?将这些重复的地方通过插件直接自动生成了,这样就不需要一行行手敲了,当然可以,下次再聊!

如果使用vscode开发,有便利工具插件

VSCode面向对象c插件开源实现

http://www.gsyq.cn/news/1641919.html

相关文章:

  • Runno沙盒安全深度剖析:为什么你的代码在浏览器中是安全的
  • 如何快速上手Swirl:Android指纹动画库的5分钟入门教程
  • 一键搞定文档转换:如何用MarkItDown将PDF、Word等数十种格式智能转为Markdown
  • ZyPlayer:你的个人影视中心,重新定义跨平台观影体验
  • 开源(Open Source)那些事儿 (一)
  • WebPShop:让Photoshop原生支持WebP格式的终极解决方案
  • 3步搞定SCAIL-2模型迁移:让AI绘画在ComfyUI中焕发新生
  • activerecord-multi-tenant 安全最佳实践:确保多租户数据隔离与访问控制
  • Cargo-script 缓存机制详解:如何加速 Rust 脚本的重复执行 [特殊字符]
  • NeSF可视化工具使用教程:用Jax3d探索3D语义场景表示的强大功能
  • Windows系统性能瓶颈深度解析与Win11Debloat优化方案
  • Kronos金融预测模型终极指南:快速上手与高效部署
  • 深度解析新型钓鱼攻击:GhostFrame与BlackForce如何绕过MFA防御
  • 电气上位机工程师系列课程
  • Swirl实战:在Android应用中实现专业级指纹识别UI
  • 5个关键步骤掌握Snipe-IT:免费开源IT资产管理系统终极指南
  • Instatic高可用配置:主备切换与故障转移完整指南
  • 三步轻松获取国家中小学智慧教育平台电子课本的完整指南
  • Marp for VS Code架构深度解析:如何用TypeScript构建现代Markdown幻灯片扩展
  • 为什么每个开发团队都需要todo[bot]:5个核心功能解析与实战演示
  • AI学术会议倒计时终极指南:2000+顶级会议投稿时间精准掌控
  • 革命性AI编码助手:深入解析Laguna XS 2.1的10大核心特性
  • Objective-C-RegEx-Categories高级用法:RxMatch对象与分组捕获完全解析
  • 告别臃肿开发环境:w64devkit如何用300MB实现完整Windows C/C++工具链
  • 企业级情感分析系统架构深度剖析与VADER实战指南
  • RetinexNet揭秘:革命性低光图像增强技术的TensorFlow实现详解
  • CTF实战:从ROT编码原理到Python自动化破解脚本开发
  • 如何利用todo[bot]优化Pull Request工作流:智能代码审查自动化指南
  • CANN算子库Transpose API
  • CANN/ops-sparse稀疏算子测试工程师