知乎全站热榜 04月19日
C 语言如何实现面向对象?
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_guoji1.html

 

文章探讨了在C语言中实现面向对象编程的可能性。作者通过对比C语言的结构体和C++的类,指出C语言可以通过结构体和自由函数的形式模拟面向对象,但这种方式在存储效率上不如C++的成员函数。文章进一步质疑了“C语言也能实现面向对象”的说法,认为C语言本身就包含面向对象的元素,而过程式编程只是局部现象。最终,文章提出了对C语言和面向对象编程之间关系的思考。

💡C语言可以通过结构体和自由函数模拟面向对象编程。文章中,作者展示了如何在C语言中使用结构体(如`dev_t`和`account_t`)以及与结构体相关的自由函数(如`account_create`、`account_deposit`等)来实现类似面向对象的功能,例如封装数据和操作数据的函数。

🤔C语言模拟OOP的存储效率问题。作者指出,C语言中通过结构体指针实现函数调用,会浪费存储空间。相比之下,C++的成员函数通过name mangling处理,除了虚函数外,不会浪费存储空间,这使得C++在实现面向对象时更具优势。

🧐对“C语言也能实现面向对象”的质疑。作者认为,C语言本身就包含了面向对象的元素,过程式编程只是局部现象。文章中通过对全局变量和自由函数的讨论,强调了过程式编程的局限性,并质疑了将C语言完全归为过程式编程的观点。

💡C语言的面向对象实现方式更接近于结构体+自由函数的形式。这种方式虽然可以实现封装和数据操作,但在存储效率和代码组织上与C++的面向对象实现方式存在差异。

1、经常有人说面向对象只是一种思想,C 语言也能实现面向对象。但是,如何做到呢?不会是结构体里面塞指针吧?typedef struct dev { int id; // 设备唯一标识符 char name[256]; // 设备名称 char type[64]; // 设备类型 void *driver_data; // 驱动程序数据 int status; // 设备状态,0 表示离线,1 表示在线 void (*init)(struct dev *device); // 初始化设备函数 void (*shutdown)(struct dev *device); // 关闭设备函数 ssize_t (*read)(struct dev *device, void *buffer, size_t size); // 设备读取函数 ssize_t (*write)(struct dev *device, const void *buffer, size_t size); // 设备写入函数 } dev_t; 需要注意!这个结构体里面的函数指针对标的不是 C++ 的成员函数,而是回调函数!如果没有回调函数的需求,没有人会这样干!如果写成 C++,那么也需要使用类似回调的方式,而不能转换成成员函数。class Dev { public: int id; // 设备唯一标识符 std::string name; // 设备名称 std::string type; // 设备类型 void *driver_data; // 驱动程序数据 int status; // 设备状态,0 表示离线,1 表示在线 // 使用 std::function 来存储回调函数 std::function init; // 初始化设备函数 std::function shutdown; // 关闭设备函数 std::function read; // 设备读取函数 std::function write; // 设备写入函数 // ... }; 为什么成员函数不能实现为结构体里塞指针呢?因为显而易见浪费存储!我一个结构体里面塞了 4 个指针,每个指针 8 字节,创建 n 个对象,浪费了 32n 字节的空间!人家 C++ 的成员函数是通过 name mangling 处理的,除了虚函数之外,不会浪费任何一点存储空间。 2、基于 1 的分析,如果要在 C 中实现 OOP,那么最终还是回到了结构体+自由函数的形式,比如:// 银行账户结构体 typedef struct account { int account_number; // 账户号码 char owner_name[256]; // 账户持有者姓名 double balance; // 账户余额 } account_t; // 创建账户 account_t* account_create(int account_number, const char *owner_name, double initial_balance); // 存款 void account_deposit(account_t *account, double amount); // 取款 void account_withdraw(account_t *account, double amount); // 查询账户余额 void account_check_balance(account_t *account); // 销毁账户 void account_destroy(account_t *account); 那么问题来了,这时候是面向对象还是面向过程? 你说这里用到了面向对象的思想,所以是面向对象。好好好,没问题,有问题的是,在算对的情况下(不考虑算错,也就是不考虑瞎写的情况),那天底下有不是面向对象思想的么?我把结构体删了,那就剩下一堆全局变量,变量就不是对象么?变量也是对象,变量是具名的对象,我说我依旧用到了面向对象思想,所以我使用的是面向对象的范式,汝能奈我何? 你说这有些过于诡辩了,全局变量只是跨函数状态的临时寄存处,类似于堆栈,比堆栈强的点只是跨函数而已,和面向对象的思想距离有点远,要算在过程式里面。好好好,那么除了做题之外,还有谁在写全局变量+自由函数的代码么?这种代码的适用面也太窄了,是不是足以忽略不计了呢?所以纯过程式就无法独立存在了? 所以我们是不是不应该说 “C 语言也能实现面向对象”,而应该说 “C 语言本身就是面向对象,过程式只是局部现象”???(dev*,>(dev*,>(dev*)>(dev*)>

Fish AI Reader

Fish AI Reader

AI辅助创作,多种专业模板,深度分析,高质量内容生成。从观点提取到深度思考,FishAI为您提供全方位的创作支持。新版本引入自定义参数,让您的创作更加个性化和精准。

FishAI

FishAI

鱼阅,AI 时代的下一个智能信息助手,助你摆脱信息焦虑

联系邮箱 441953276@qq.com

相关标签

C语言 面向对象 OOP 结构体 编程思想
相关文章