mru*_*jay 5 c oop procedural-programming
我对数据抽象的理解是隐藏用户的技术细节并仅显示必要的细节.因此,数据抽象是一种OOP功能.我的问题是:C是否也支持数据抽象?
如果是这样,为什么数据抽象是面向对象的编程语言特性而不是过程语言特性?
如果我的问题的答案是否定的,那么C中的结构,枚举呢?他们还隐藏了用户的详细信息.
在C语言中进行面向对象编程当然是可能的.请记住,例如,第一个C++编译器实际上是C++到C的转换器,Python VM是用C语言编写的.将所谓的OOP语言与其他语言区别开来的是更好的支持这些结构,例如在语法中.
提供抽象的一种常见方法是函数指针.查看下面Linux内核源代码中的结构(来自include/linux/virtio.h).
/**
* virtio_driver - operations for a virtio I/O driver
* @driver: underlying device driver (populate name and owner).
* @id_table: the ids serviced by this driver.
* @feature_table: an array of feature numbers supported by this driver.
* @feature_table_size: number of entries in the feature table array.
* @probe: the function to call when a device is found. Returns 0 or -errno.
* @remove: the function to call when a device is removed.
* @config_changed: optional function to call when the device configuration
* changes; may be called in interrupt context.
*/
struct virtio_driver {
struct device_driver driver;
const struct virtio_device_id *id_table;
const unsigned int *feature_table;
unsigned int feature_table_size;
int (*probe)(struct virtio_device *dev);
void (*scan)(struct virtio_device *dev);
void (*remove)(struct virtio_device *dev);
void (*config_changed)(struct virtio_device *dev);
#ifdef CONFIG_PM
int (*freeze)(struct virtio_device *dev);
int (*restore)(struct virtio_device *dev);
#endif
};
Run Code Online (Sandbox Code Playgroud)
probe,scan,remove诸如此类都是一个I/O驱动程序将自己所有的函数指针.然后,内核可以为任何I/O驱动程序调用这些函数,而无需了解有关该设备的任何信息.这是C中的抽象示例.请参阅此文章以阅读有关此特定示例的更多信息.
另一种形式的数据抽象是不透明的指针.在头文件中声明了不透明数据类型,但从不公开该定义.不知道类型定义的代码永远不能访问它的值,只使用它的指针.请参阅Wikipedia上的不透明数据类型和不透明指针.
您可能遇到的不透明数据类型的示例FILE来自stdio.h.所有操作系统都使用相同的接口,尽管FILE *指向的实际数据不同.您可以FILE *通过fopen一系列其他函数调用来调用和操作它,但您可能看不到它指向的数据.
要了解有关CI中面向对象编程的更多信息,请参阅ANSI-C中的免费在线书籍面向对象编程.看看这篇Dobbs博士的文章.相关问题:C中的面向对象,你能用C 编写面向对象的代码吗?.
在 C 中隐藏很容易,只需要强制转换即可。
OOP可能会完成,但我想说,有些功能并不是很容易获得(例如:继承),我想多态性甚至可能实现,但从未在家里尝试过!
本机 C++ 库的C接口很常见,例如:
void *obj_create(void); /* return obscure ptr */
int obj_method(void *obj, int somearg);
void obj_destroy(void *obj);
Run Code Online (Sandbox Code Playgroud)
将私有标头与公共分布式标头分开,就是这样。
编辑
在AmigaOS中,有一个 C 基本 OOP 实现,已经运行了多年,至少仍然在AROS项目中使用,该实现称为BOOPSI,也是一些 GUI 小工具(小部件)的基础,但只能用于描述对象,这里有一个小介绍(在Amiga Rom 内核参考手册中展示了如何使用它向更多对象广播信号,这是 Qt 插槽/信号实现的先驱)。
过去几天我一直在研究Nim lang ,它生成 C 代码(添加一些运行时,可能被禁用)以与 gcc/clang/tinycc 等后端一起编译,并且它支持一些 OOP。