6

What I understood about data abstraction is hiding technical details from user and showing only necessary details. So data abstraction is an OOP feature. My question is: does C also support data abstraction?

If so, why is data abstraction an Object Oriented Programming language feature and not a procedural language feature?

If the answer to my question is no, then what about structures, enums in C? They also hide details from users.

4

2 回答 2

5

在 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 中的抽象示例。请参阅本文以了解有关此特定示例的更多信息。

另一种数据抽象形式是不透明指针。不透明数据类型在头文件中声明,但从不公开定义。不知道类型定义的代码永远无法访问它的值,只能使用指向它的指针。请参阅维基百科上的不透明数据类型不透明指针

您可能遇到的不透明数据类型的示例FILE来自 stdio.h。FILE *尽管 a指向的实际数据不同,但所有操作系统都使用相同的接口。您可以FILE *通过调用fopen并使用一系列其他函数调用来操作它,但您可能看不到它指向的数据。

要了解有关 CI 中面向对象编程的更多信息,请推荐免费在线书籍ANSI-C 中的面向对象编程。看看这篇 Dobbs 博士的文章。相关问题:C 中的面向对象你能用 C 编写面向对象的代码吗?.

于 2015-07-22T14:35:12.267 回答
2

在 C 中隐藏很容易,只是cast的问题。

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 小工具(小部件)的基础,但可以用来描述objects,这里是一个小介绍(在Amiga Rom Kernel Reference Manual中,展示了如何使用它向更多对象广播信号,这是 Qt 的插槽/信号实现的先驱)。

过去几天我一直在研究Nim lang,它生成 C 代码(添加一些运行时,可能已禁用)以使用 gcc/clang/tinycc 等后端进行编译,并且它支持一些 OOP。

于 2013-10-06T14:32:08.237 回答