【问题标题】:Data Abstraction in CC中的数据抽象
【发布时间】:2013-10-13 02:50:28
【问题描述】:

我对数据抽象的理解是对用户隐藏技术细节,只显示必要的细节。所以数据抽象是一个面向对象的特性。我的问题是:C 是否也支持数据抽象?

如果是这样,为什么数据抽象是面向对象的编程语言特性而不是过程语言特性?

如果我的问题的答案是,那么 C 中的结构和枚举呢?他们还向用户隐藏详细信息。

【问题讨论】:

  • “为什么数据抽象是面向对象的编程语言特性而不是过程语言特性?” - 事实并非如此。
  • 那为什么到处都提到它是 OOP 特性而不是过程语言特性呢??
  • 你得出的结论是所有男人都是猫,但事实并非如此。数据抽象是一件令人向往的事情。 OOP 是一种提供数据抽象的编程风格。您可以通过多种不同方式实现数据抽象。
  • 最重要的是,完全可以用 C 语言编写面向对象的风格。它只是比其他语言更冗长和嘈杂。
  • 看看GObject

标签: c oop procedural-programming


【解决方案1】:

在 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 gadget (widget) 的一部分,但只能用于描述 objects,这里有一个小的 introduction(在 Amiga Rom Kernel Reference Manual 中显示了如何使用它可以向更多对象广播信号,这是 Qt 的插槽/信号实现的先驱)。

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

【讨论】:

  • 另一种更明显的数据隐藏形式是在标头中使用 extern 关键字声明结构,然后在模块中定义该结构。只有该模块中的函数知道该结构的结构,但其他模块中的函数仍可能使用该结构的副本。
【解决方案2】:

当然可以在 C 中进行面向对象编程。请记住,例如first C++ compiler 实际上是一个 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
};

probescanremove 等等都是 I/O 驱动程序自己设置的函数指针。然后内核可以为任何 I/O 驱动程序调用这些函数,而无需了解有关设备的任何信息。这是 C 中的抽象示例。请参阅 this article 以了解有关此特定示例的更多信息。

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

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

要了解有关 C 中面向对象编程的更多信息,我推荐免费在线书籍Object Oriented Programming in ANSI-C。查看this Dr Dobbs 文章。相关问题:Object orientation in CCan you write object oriented code in C?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-09-08
    • 2010-12-13
    • 1970-01-01
    • 2012-11-22
    • 1970-01-01
    • 1970-01-01
    • 2014-08-13
    • 1970-01-01
    相关资源
    最近更新 更多