C для объектно-ориентированного программиста - PullRequest
9 голосов
/ 21 сентября 2009

Изучив Java и C ++, я выучил OO-путь. Я хочу начать довольно амбициозный проект, но я хочу сделать это в C. Я знаю, как разбить проблемы на классы и как превратить их в иерархию классов. Я знаю как абстрагировать функциональность в абстрактные классы и интерфейсы. Я даже несколько опытен в использовании полиморфизма эффективным способом.

Проблема в том, что когда у меня возникает проблема, я знаю, как это сделать, только объектно-ориентированным способом. Я стал слишком зависимым от философии и методологии объектно-ориентированного дизайна.

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

Как вы представляете сложные концепции, используя только не объектно-ориентированные struct с? Как обойти отсутствие перегрузки функций? Какие подсказки и уловки для процедурного мышления?

Ответы [ 7 ]

4 голосов
/ 21 сентября 2009

Процедурный способ состоит в том, чтобы, с одной стороны, иметь ваши структуры данных, а с другой - ваши алгоритмы. Затем вы берете свои структуры данных и передаете их своим алгоритмам. Без инкапсуляции для этого требуется несколько более высокий уровень дисциплины, и если вы повышаете уровень абстракции, чтобы упростить его выполнение, вы делаете значительную часть ОО в C.

1 голос
/ 21 сентября 2009

Не думай, что С полным ООП. Если вам нужно использовать C, вы должны изучить процедурное программирование. Для этого не потребуется больше времени, чем для изучения того, как реализовать все функции ООП в C. Кроме того, базовая инкапсуляция, вероятно, подойдет, но многие другие функции ООП накладываются на производительность, когда вы имитируете их (а не когда язык разработан поддерживать ООП). Затраты могут быть огромными, если вы строго следуете методологии проектирования C ++, чтобы представлять все мелочи как объекты. Языки программирования имеют конкретные цели в дизайне. Когда вы нарушаете границу, вы всегда должны платить что-то как стоимость.

1 голос
/ 21 сентября 2009

Вы берете обратную поездку, которую старые программисты на Си делали для изучения ОО.

Еще до того, как c ++ стал стандартом, О-технологии использовались в C.

Они включали определение структур с указателем на srtuct (обычно это называется ...) Затем определяем функции указателя в структуре и во время выполнения инициализируем эти указатели на соответствующие функции. Все эти функции получили в качестве первого параметра указатель структуры this.

1 голос
/ 21 сентября 2009

Инструментарий C состоит из функций, указателей функций и макросов. Указатели функций могут использоваться для эмуляции полиморфизма.

1 голос
/ 21 сентября 2009

Я думаю, у вас есть хороший план. Делать вещи полностью ОО-способом в С, хотя это вполне возможно, достаточно боли, что вы все равно скоро бросите это. (Не борись за язык.)

Если вам нужно философское утверждение о сопоставлении пути ОО к пути С, отчасти это происходит путем подталкивания создания объекта на один уровень вверх. Модуль все еще может реализовать свой объект в виде черного ящика, и вы все равно можете использовать разумный стиль программирования, но в основном это слишком большая боль, чтобы действительно скрыть объект, поэтому вызывающая сторона выделяет его и передает его вниз, а не выделяет модуль. и вернуть его обратно. Вы обычно используете геттеры и сеттеры или реализуете их как макросы.

Учтите также, что все упомянутые вами абстракции - это относительно тонкий слой поверх обычных structs, так что вы не очень далеко от того, что хотите сделать. Это просто не так хорошо упаковано.

0 голосов
/ 21 сентября 2009

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

Мне пришлось работать в Си после того, как я в основном имел опыт объектно-ориентированной работы. C допускает некоторый уровень концепций объектов, которые можно преодолеть. На работе мне пришлось реализовать красно-черное дерево на C для использования в алгоритме Sweep-Line , чтобы найти точки пересечения в наборе сегментов. Поскольку в алгоритме использовались разные функции сравнения, я использовал указатели на функции для достижения того же эффекта, что и лямбда-выражения в схеме или делегаты в C #. Это работало хорошо, а также позволяло сбалансированному дереву многократно использоваться.

Другая особенность сбалансированного дерева заключалась в использовании пустых указателей для хранения произвольных данных. Опять же, указатели void и function в C - это боль (если вы не знаете их входов и выходов), но их можно использовать для приблизительного создания общей структуры данных.

Последнее замечание: используйте правильный инструмент для работы. Если вы хотите использовать C просто для овладения процедурной техникой, то выберите задачу, которая хорошо подходит для процедурного подхода. У меня не было выбора в этом вопросе (унаследованное приложение написано на C, и люди требуют мира и отказываются войти в 21-й век), поэтому я должен был быть креативным. C отлично подходит для низких / средних абстракций с компьютера, например, если вы хотите написать программу проверки пакетов в командной строке.

0 голосов
/ 21 сентября 2009

Стандартный способ сделать полиморфное поведение в C состоит в использовании указателей на функции. Вы найдете множество API C (таких как стандартные qsort(3) и bsearch(3)), которые принимают указатели функций в качестве параметров; некоторые нестандартные, такие как qsort_r, принимают указатель функции и указатель context (в данном случае thunk), который не служит никакой другой цели, кроме как быть переданным обратно функция обратного вызова. Указатель контекста работает точно так же, как указатель this в объектно-ориентированных языках при работе с функциональными объектами (например, функторами).

Смотри также:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...