我对数据抽象的理解是对用户隐藏技术细节,只显示必要的细节。因此,数据抽象是一个 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
};
probe
、scan
、remove
等都是 I/O 驱动程序自己设置的函数指针。然后,内核可以为任何 I/O 驱动程序调用这些函数,而无需了解有关设备的任何信息。这是 C 语言中抽象的一个示例。请参阅本文以了解有关此特定示例的更多信息。
数据抽象的另一种形式是不透明指针。在头文件中声明不透明数据类型,但定义永远不会公开。不知道类型定义的代码永远无法访问它的值,只能使用指向它的指针。请参阅维基百科上的不透明数据类型和不透明指针。
您可能遇到的不透明数据类型的示例来自 stdio.h FILE
。所有操作系统都使用相同的接口,尽管FILE *
指向的实际数据不同。您可以通过调用fopen
来获取FILE *
,并使用一系列其他函数调用对其进行操作,但您可能看不到它指向的数据。
要了解有关 C 语言中面向对象编程的更多信息,我推荐免费的在线书籍 ANSI-C 中的面向对象编程。看看这篇多布斯博士的文章。相关问题: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);
将私有标头与公共分发的标头分开,即。
编辑
在 AmigaOS 中,有一个 C 基本的 OOP 实现已经工作了多年,至少在 AROS 项目中仍在使用,该实现称为 BOOPSI,也是一些 GUI 小工具(小部件(的基础,但只能用于描述对象,这里有一个小介绍(在 Amiga Rom 内核参考手册中,展示了如何使用它将信号广播到更多对象, Qt的插槽/信号实现的先驱(。
在过去的几天里,我一直在研究 Nim lang,它生成 C 代码(添加一些运行时,可能会被禁用(以使用 gcc/clang/tinycc 等后端进行编译,并且它支持一些 OOP。