Объектно-ориентированное программирование на C [дубликат]

_ является допустимым символом для имени переменной, а $FOLDERNAME_ не существует.

echo "$BACKUP_DESTINATION/$DATE_FOLDER/${FOLDERNAME}_$FILENAME"
54
задан Community 23 May 2017 в 12:33
поделиться

13 ответов

Вы можете реализовать полиморфизм с регулярными функциями и виртуальными таблицами (VTable). Вот довольно аккуратная система, которую я изобрел (на основе C ++) для упражнения программирования: alt text

конструкторы выделяют память, а затем вызовут функцию init Class, где память инициализируется. Каждая функция init должна также содержать статическую структуру VTable, которая содержит указатели виртуальной функции (NULL для чистого виртуального). Функции INITION производных класса Вызывают функцию INIT SUPERCASS, прежде чем делать что-либо еще.

Очень хорошая API может быть создана путем реализации виртуальных функций обертки (не путать с функциями, указанными на vtables) следующим образом (Добавить Static Inline перед ним, если вы сделаете Это в заголовке):

int playerGuess(Player* this) { return this->vtable->guess(this); }

Одиночное наследование может быть сделано путем злоупотребления бинарной раскладкой структуры: alt text

Обратите внимание, что множественное наследование является Месмером, как тогда вам часто необходимо регулировать значение указателя при отливок между типами иерархии.

Другие данные типа, которые также могут быть добавлены в виртуальные таблицы. Примеры включают в себя информацию о времени выполнения (например, тип типа в виде строки), связывание к SuperClass VTable и цепочкой деструктора. Вы, вероятно, хотите виртуальные деструкторы, где производный класс деструктора демотирует объект к своему суперклассным классам, а затем рекурсивно вызывает деструктора этого и так далее, пока не достигнут деструктор базового класса, и что, наконец, освобождает структуру.

Инкапсуляция была выполнена путем определения структур в Player_Protected.h и реализует функции (указанные на VTable) в Player_Protected.c, и аналогично для полученных классов, но это довольно неуклюже, и он ухудшает производительность (как Виртуальные обертки не могут быть поставлены в заголовки), поэтому я бы порекомендовал против него.

76
ответ дан 7 November 2019 в 07:47
поделиться

Как бы вы эмулировали инкапсуляцию и наследство, хотя?

На самом деле, инкапсуляция - это самая легкая часть. Инкапсуляция - это дизайн философия .

Например, файл Windows API полностью инкапсулируется. Когда вы открываете файл, вы вернете непрозрачный объект, который содержит всю информацию о состоянии для файла «Объект». Вы передаете эту ручку обратно к каждому из файлов IO API. Инкапсуляция на самом деле на самом деле лучше лучше, чем C ++, потому что нет файла заголовка публичного заголовка, на которой люди могут посмотреть и увидеть имена ваших личных переменных.

Наследование сложнее, но вообще не нужно для того, чтобы ваш код был ориентирован на объект. В некоторых способах агрегация лучше, чем наследство, а агрегация так же легка в C, как в C ++. См. это , например.

В ответ на Нил увидеть Википедия для объяснения того, почему наследство не нужно для полиморфизма.

Участок США написал ориентированные объектно-ориентированные годы, до того, как были доступны компиляторы C ++, это ума не набор инструментов.

8
ответ дан 7 November 2019 в 07:47
поделиться

Основная структура Corefoundation Apple Corefoundation была фактически написана таким образом, чтобы его «объекты» могли удвоить в качестве объектов в объекте-C, фактический язык OO. Довольно большое подмножество рамки является открытым источником на сайте Apple AS CF-Lite . Может быть полезным тематическим исследованием в основных структурах уровня ОС.

5
ответ дан 7 November 2019 в 07:47
поделиться

Да.

Реальный вопрос заключается в сколько?

областей, в которых они могут вносить эффективный вклад:

  • Стандартные веб-технологии : HTTP, CSS, XHTML, XML, XSLT
  • Узоров : MVC, Gang of Four и т.д.
  • Высокоуровневый дизайн

Области, в которых они не смогут эффективно участвовать:

  • Настройка производительности
  • Безопасность
  • Низкоуровневая конструкция
-121--5086172-

Список-список-входов-двоичный:

Start traversing the input list
For each sublist:
    Output 0xFF 0xFE
    For each item in the sublist:
        Output the item as a stream of bits, LSB first.
          If the pattern 0xFF appears anywhere in the stream,
          replace it with 0xFF 0xFD in the output.
        Output 0xFF 0xFC

Декодирование:

If the stream has ended then end any previous list and end reading.
Read bits from input stream. If pattern 0xFF is encountered, read the next 8 bits.
   If they are 0xFE, end any previous list and begin a new one.
   If they are 0xFD, assume that the value 0xFF has been read (discard the 0xFD)
   If they are 0xFC, end any current integer at the bit before the pattern, and begin reading a new one at the bit after the 0xFC.
   Otherwise indicate error. 
-121--2771391-

С немного большей высоты и считая проблему скорее более открытой, чем как Это не обязательно означает, что функция должна быть физически прикреплена к объекту, как это происходит в популярных языках, которые поддерживают парадигму ООП, например, в C++:

struct T
{
   int data;
   int get_data() const { return data; }
};

Я бы предложил внимательнее рассмотреть GTK + Object and Type System . Это блестящий пример ООП, реализованного на языке программирования Си:

GTK + реализует собственный пользовательский объект система, которая предлагает стандартные объектно-ориентированные элементы, такие как наследование и виртуальная функция

Ассоциация также может быть договорной и традиционной.

Что касается методов инкапсуляции и скрытия данных, популярным и простым может быть Непрозрачный указатель (или Непрозрачный тип данных) - его можно передать, но для загрузки или хранения любой информации необходимо вызвать связанную функцию, которая умеет говорить с объектом, скрытым за этим непрозрачным указателем.

Другой, похожий, но другой - тип теневых данных - проверьте эту ссылку, где Джон Джаггер дает прекрасное объяснение этой не самой известной технологии.

5
ответ дан 7 November 2019 в 07:47
поделиться

Библиотеки GTK и Glib используют макросы для литых объектов к различным типам.
add_widget (gtk_widget (mybutton));
Я не могу сказать, как это сделано, но вы можете прочитать их источник, чтобы точно узнать, как это сделано.

2
ответ дан 7 November 2019 в 07:47
поделиться

Взгляните на то, как слой VFS работает в ядре Linux для примера рисунка наследования. Файловые операции для различных файловых систем «наследовать» набор функций общих файлов (например, Generic_file_aio_read () , Generic_file_llseek () ...), но может переопределить их своими Реализации (например, NTFS_file_aio_write () ).

2
ответ дан 7 November 2019 в 07:47
поделиться

Для большого примера объектно-ориентированного программирования в C, посмотрите на источник POV-RAY с нескольких лет назад - версия 3.1G особенно хорош. «Объекты» были структурными с указателями функций, конечно. Макросы использовались для обеспечения основных методов и данных для абстрактных объектов, а полученные классы были структурами, которые начались с этого макроса. Однако не было никакой попытки справиться с частным / публичным. Вещи, которые можно увидеть, были в файлах и деталях реализации были в файлах .C, в основном, за исключением многих исключений.

Были некоторые аккуратные хитрости, которые я не вижу, как можно перенести на C ++ - например, преобразование одного класса на другое, но похожее на лету, просто переназнавая указатели функции. Простые на сегодняшние динамические языки. Я забыл детали; Я думаю, что это могло быть пересечение и союзные объекты CSG.

http://www.povraй.org/

1
ответ дан 7 November 2019 в 07:47
поделиться

Приятная статья и обсуждение, касающиеся объекта-C здесь:

http://cocoawithlove.com/2009/10/Objective-c-niche-why-it-survives-in.html

2
ответ дан 7 November 2019 в 07:47
поделиться

Определенно посмотрите на Цели-С.

typedef struct objc_object {
    Class isa;
} *id;

typedef struct objc_class {
    struct objc_class *isa;
    struct objc_class *super_class
    const char *name;
    long version;
    long info
    long instance_size;
    struct objc_ivar_list *ivars;
    struct objc_method_list **methodLists;
   struct objc_cache *cache;
   struct objc_protocol_list *protocols;
} *Class;

Как видите, информация о наследовании, наряду с другими деталями, хранится в структуре класса (удобно, что класс также может рассматриваться как объект).

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

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

2
ответ дан 7 November 2019 в 07:47
поделиться

Интересный бит истории. CFRONT , исходный код реализации C ++ C Code Code, а затем требует компилятора C, чтобы на самом деле создать окончательный код. Итак, все, что могло быть выражено в C ++, может быть написано как C.

1
ответ дан 7 November 2019 в 07:47
поделиться

Один из способов обрабатывать наследование - это вложенные структуры:

struct base
{
    ...
};

void method_of_base(base *b, ...);

struct child
{
    struct base base_elements;
    ...
};

Вы можете тогда сделать такие звонки:

struct child c;
method_of_base(&c.b, ...);
1
ответ дан 7 November 2019 в 07:47
поделиться

Как бы вы эмулировали инкапсуляцию и наследование?

На самом деле инкапсуляция является самой простой частью. Инкапсуляция является конструктивной философией, она не имеет ничего общего с языком и всем, что касается того, как вы думаете о проблемах.

Например, API-интерфейс Windows FILE полностью инкапсулирован. При открытии файла возвращается непрозрачный объект, содержащий всю информацию о состоянии файла «object». Вы передаете этот дескриптор обратно каждому из файлов io apis. Инкапсуляция на самом деле намного лучше, чем C++, потому что нет открытого файла заголовка, который люди могли бы просматривать и видеть имена ваших частных переменных.

Наследование сложнее, но это совсем не обязательно для того, чтобы ваш код был ориентирован на объект. В некотором смысле агрегация лучше наследования, и агрегация так же проста в C, как и в C++. см., например, это .

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

Мы, старожилы, писали объектно-ориентированный код за годы до того, как были доступны компиляторы C++, это набор ума, а не набор инструментов.

-121--1836883-

Рамка CoreFoundation на базе C от Apple была написана таким образом, чтобы ее «объекты» могли удвоиться как объекты в Objective-C, фактическом языке OO. Довольно большое подмножество рамки - открытый исходный код на сайте Apple как CF-Lite . Может быть полезным тематическим исследованием в основной структуре на уровне ОС, сделанным таким образом.

-121--1836884-

Вы можете посмотреть на Objective-C, это в значительной степени то, что он делает. Это всего лишь фронтэнд, который компилирует код Objective-C OO до C.

0
ответ дан 7 November 2019 в 07:47
поделиться

Вы читали "Библию" на эту тему? Смотрите Object Oriented C...

29
ответ дан 7 November 2019 в 07:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: