Абстракция данных в C

Что я понял об абстракции данных, так это скрытие технических деталей от пользователя и отображение только необходимых деталей. Таким образом, абстракция данных — это функция ООП. Мой вопрос: поддерживает ли C также абстракцию данных?

Если да, то почему абстракция данных является функцией объектно-ориентированного языка программирования, а не функцией процедурного языка?

Если ответ на мой вопрос нет, то как насчет структур, перечислений в C? Они также скрывают детали от пользователей.


person mrutyunjay    schedule 06.10.2013    source источник
comment
Почему абстракция данных является функцией объектно-ориентированного языка программирования, а не функцией процедурного языка? - Это не так.   -  person Oliver Charlesworth    schedule 06.10.2013
comment
Тогда почему это везде упоминается как функция ООП, а не как функция процедурного языка??   -  person mrutyunjay    schedule 06.10.2013
comment
Вы заключаете, что все мужчины - кошки, но это не так. Абстракция данных — желанная вещь. ООП — это стиль программирования, обеспечивающий абстракцию данных. Вы можете добиться абстракции данных разными способами.   -  person Kerrek SB    schedule 06.10.2013
comment
Вдобавок ко всему, на C вполне возможно писать в объектно-ориентированном стиле. Просто он более многословен и зашумлен, чем в других языках.   -  person Kerrek SB    schedule 06.10.2013
comment
Взгляните на GObject.   -  person Jean Pierre Dudey    schedule 22.07.2015


Ответы (2)


Конечно, можно делать объектно-ориентированное программирование на C. Помните, что, например. первый компилятор C++ на самом деле был транспилером C++ в C, виртуальная машина Python написана на C и т. д. Что отличает так называемые языки ООП от других, так это лучшая поддержка этих конструкций, например, в синтаксисе.

Одним из распространенных способов обеспечения абстракции являются указатели на функции. Посмотрите на структуру исходного кода ядра 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 и так далее — все это указатели на функции, которые устанавливает драйвер ввода-вывода. Ядро затем может вызывать эти функции для любого драйвера ввода/вывода без необходимости знать что-либо об устройстве. Это пример абстракции в C. См. эту статью, чтобы узнать больше об этом конкретном примере.

Другой формой абстракции данных являются непрозрачные указатели. Непрозрачный тип данных объявляется в заголовочном файле, но определение никогда не раскрывается. Код, который не знает определения типа, никогда не сможет получить доступ к его значению, а только использовать указатели на него. См. Непрозрачный тип данных и Непрозрачный указатель в Википедии.

Примером непрозрачного типа данных, с которым вы, вероятно, сталкивались, является FILE из stdio.h. Один и тот же интерфейс используется во всех операционных системах, хотя фактические данные, на которые указывает FILE *, различаются. Вы можете получить FILE *, вызвав fopen, и манипулировать им с помощью ряда других вызовов функций, но вы можете не видеть данные, на которые он указывает.

Чтобы узнать больше об объектно-ориентированном программировании на C, я рекомендую бесплатную онлайн-книгу Object Oriented Programming. в ANSI-C. Ознакомьтесь с этой статьей доктора Доббса. Связанные вопросы: Ориентация объекта в C и Можете ли вы писать объектно-ориентированный код на C?.

person jacwah    schedule 22.07.2015

Скрыть в C легко, это вопрос приведения.

ООП может быть сделано, но я бы сказал, что некоторые функции не очень удобны для получения (например, наследование). Я думаю, что полиморфизм может быть даже достигнут, но никогда не пробовал дома!

C интерфейсы для нативных библиотек C++ распространены, например:

void *obj_create(void); /* return obscure ptr */
int obj_method(void *obj, int somearg);
void obj_destroy(void *obj);

Отделение частных заголовков от общедоступных распределенных и т.д.

изменить

В AmigaOS есть базовая реализация ООП на C, которая работает годами и до сих пор используется из AROS, реализация называется BOOPSI и также является основой для некоторые из гаджетов с графическим интерфейсом (виджет), но их можно использовать только для описания объектов, здесь небольшой введениеСправочном руководстве по ядру Amiga Rom показано, как использовать его для передачи сигнала большему количеству объектов, первая реализация слотов/сигналов в Qt) .

Я изучал язык Nim в последние дни, он генерирует код C (добавьте немного время выполнения, которое может быть отключено) для компиляции с такими бэкендами, как gcc/clang/tinycc, и он поддерживает некоторые ООП.

person Alex    schedule 06.10.2013
comment
Еще одна более очевидная форма сокрытия данных — объявление структуры с ключевым словом extern в заголовке, но затем определение этого strict в модуле. Только функции в этом модуле знают структуру структуры, но функции в других модулях могут по-прежнему использовать копию этой структуры. - person Benjamin Leinweber; 06.10.2013