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

函数指针 + 结构体 = C 语言的“对象模型”?——从 C 到 C++ / Java 的本质统一

一、为什么 C 语言“没有对象”,却处处是对象?

很多人说:

C 是面向过程,C++ / Java 是面向对象。

但你只要看过 Linux 内核、驱动、HAL、FFmpeg、libc,就会发现:

👉到处都是 struct + 函数指针。

比如经典结构:

typedef struct { void (*open)(void* self); void (*close)(void* self); } DeviceOps; typedef struct { DeviceOps* ops; int fd; } Device; void device_open(Device* d) { d->ops->open(d); }

这真的只是“面向过程”吗?

其实不是。
👉这是 C 语言手写的“对象模型”。

tips:对象模型”可以简单理解为:像 Java 里定义接口 → 写接口实现类 → 用实现类对象,通过接口去调用方法。

二、这段 C 代码,本质上已经具备 OOP 全套能力

上面这段代码已经同时具备:

  • ✅ 数据(fd)

  • ✅ 行为(open / close)

  • ✅ 接口抽象(DeviceOps)

  • ✅ 回调机制(函数指针)

  • ✅ 多态(ops 指向不同实现)

  • ✅ this/self 机制(void* self)

这在设计层面,已经是一个完整的“对象系统”。

三、逐项拆解:C 是如何“手搓 OOP”的

1️⃣ 接口(函数表)

typedef struct { void (*open)(void* self); void (*close)(void* self); } DeviceOps;

这本质就是:
👉接口 / 虚函数表 / 回调集合

2️⃣ 对象(数据 + 接口指针)

typedef struct { DeviceOps* ops; int fd; } Device;

等价于:

  • 成员变量
  • 虚函数表指针

3️⃣ 方法调用(多态)

d->ops->open(d);

这里发生了三件事:

  • 通过 ops 找接口
  • 通过接口找实现
  • 把 d 作为 self 传入

👉 这就是虚函数调用

四、翻译成 Java,会发生什么?

C 版本核心调用

d->ops->open(d);

Java 直译版

d.ops.open(d);

Java 正统面向对象写法

d.open();

因为:

  • C 需要你手动维护 self
  • Java 编译器 / 虚拟机帮你维护 this

Java 完整对应结构

接口(C 的 DeviceOps)
interface Device { void open(); void close(); }

实现类(某个具体设备)

class FileDevice implements Device { int fd; @Override public void open() { } }

多态调用

Device d = new FileDevice(); d.open();

👉 本质和 C 的:

d->ops->open(d);

完全一致。

五、翻译成 C++,你会看到“虚函数表真身”

class Device { public: virtual void open() = 0; virtual void close() = 0; int fd; };

编译器背后做的事情,和你在 C 里写的:

DeviceOps* ops;

几乎一模一样。

👉 C++ 只是帮你自动生成并维护了那张函数表。

六、函数指针模型 = 回调模型 = 对象模型

普通回调:

register_callback(on_event);

对象模型:

device->ops->on_event(device);

区别只有一个:

👉 对象模型 =一组有语义的回调 + 绑定的数据结构

这也是为什么系统层大量使用 struct + 函数指针:

  • Linux driver
  • Binder driver
  • HAL module
  • FFmpeg / libuv / libc

👉 全部都是“接口 + 实现 + 回调 + 多态”。

七、为什么系统层更爱 C 风格“对象模型”?

因为它:

  • ✅ ABI 稳定

  • ✅ 内存布局可控

  • ✅ 无运行时依赖

  • ✅ 跨语言

  • ✅ 性能可预测

  • ✅ 可用于内核 / 驱动 / 启动阶段

而 C++ / Java:

  • 是在此模型之上,提供自动化和安全封装。

八、一句话本质总结(系统工程师版)

👉 面向对象不是语法,是设计思想。
👉 C 用函数指针实现对象。
👉 C++ 用编译器实现对象。
👉 Java 用虚拟机实现对象。

九、对 NDK / Android 系统方向的意义

你以后会不断看到:

  • Binder 的 struct + ops

  • HAL 的 hw_module_t

  • Linux 的 file_operations

  • FFmpeg 的 AVCodec

你会发现:

👉它们全都是这一个模型。

当你真正理解“函数指针 + struct = 对象模型”,你就已经具备:

✅ 系统接口设计能力
✅ 框架层阅读能力
✅ 架构抽象能力

十、终极总结

C :手动对象系统
C++ :编译器对象系统
Java :虚拟机对象系统

底层实现不同,抽象思想完全统一。

http://www.cnnetsun.cn/news/558231.html

相关文章:

  • 提示工程+Agentic AI:如何让个性化推荐从“猜你喜欢”到“懂你所需”?
  • 01. 学习教程链接
  • 救命神器10个AI论文工具,助本科生轻松搞定毕业论文!
  • MindSpore开发之路(二十七):未来展望——AI与科学计算的融合
  • 2025年山东大学计算机考研复试机试真题(解题思路 + AC 代码)
  • Unity3D AI Navigation 详解:从基础概念到实战应用
  • 【day 35】模型可视化与推理
  • AI新闻热点提取教程:10分钟部署,媒体人必备
  • 跨境电商智能风控:实体识别+欺诈检测,3小时验证
  • 智能政务文档处理:敏感信息自动脱敏,合规优先
  • 智能体多语言支持测试:云端GPU秒切语言包,0等待
  • 科研论文实体识别方案:云端Jupyter环境,学生特惠
  • Flutter 框架跨平台鸿蒙开发 —— `dart:math` 库之计算性能深度剖析
  • 教育领域实体识别:定制化学科知识图谱,精准教学
  • 没显卡如何玩转AI攻防?云端T4实例1小时1块,攻防演练神器
  • AI安全工程师速成:30小时实战课程+配套GPU资源打包
  • 隐私计算+AI检测:云端安全屋破解数据孤岛
  • 一个男人怕你跑掉,才会有这 9 种憨憨操作,笑不活了!
  • 【obsidian指南】配置obsidian git插件,实现obsidian数据定时同步到github仓库(Mac电脑)
  • 什么是NTA
  • HTML打包APK(安卓APP)中下载功能常见问题和详细介绍
  • 导师推荐8个AI论文写作软件,继续教育学生轻松搞定论文!
  • 多时区团队协作:云端AI侦测模型24小时持续训练方案
  • AI智能体负载测试:模拟万人并发,成本不到100元
  • 智能巡检模型联邦学习:多分支数据协同训练实践
  • 2025年中南大学计算机考研复试机试真题(解题思路 + AC 代码)
  • 实体识别模型实战:云端GPU10分钟出结果,新手指南
  • AI威胁侦测保姆级指南:小白10分钟部署,1块钱起体验
  • apexnav是什么项目呢?
  • 隐私计算+AI侦测:联邦学习云端方案保护数据安全