Борьба с C от объектно-ориентированной земли?

Когда мне представляются проблемы с программированием, я, естественно, начинаю разбивать их на логические объекты в моей голове. У кого есть какая ответственность, кто владеет тем, кто проистекает от чего и т. Д.

Я борюсь с C. Я просто не понимаю, как делать вещи на языке процедур.

Может ли опытный программист C объяснить, как я должен думать о своих программах во время разработки?

Например, я хочу написать собственный class Семафор. Естественно, мне нужна структура данных очереди для моей программы, которую я тоже хотел бы написать. Если бы мне нужно было сделать это на Java или C #, я мог бы просто взломать быстрый class Queue и создать новый экземпляр в моем classе Semaphore.

Но в C нет объектов. Итак, нужно ли мне встраивать все поведение моей структуры данных очереди?

Может ли кто-нибудь помочь мне «получить это»?

Связано : что является лучшим способом планирования и организации разработки приложения в c

Но в C нет объектов. Итак, нужно ли мне встраивать все поведение моей структуры данных очереди?

Нет.

Сделай это.

  1. Определите свой class, но вы чувствуете себя комфортно, делая OO-дизайн.

  2. Напишите атрибуты вашего classа как структуру языка C.

  3. Поместите эту структуру в файл заголовка вместе со всеми функциями, которые работают с этой структурой. Убедитесь, что MyStruct * self является первым аргументом для всех этих «функций метода».

  4. Напишите модуль C со всеми органами функций метода.

Безумное ОО в C. Оно работает хорошо. Просто будьте дисциплинированы в том, чтобы поместить все в структуру, которая вам нужна – переменные public и private instance – все.

Как правило, избегайте использования личных переменных. У вас нет полной возможности компилятора OO, поэтому не беспокойтесь о низкоценных функциях, таких как «частный» или «защищенный».

Я хотел бы изменить ответ С. Лотта на использование непрозрачного указателя для скрытия данных элементов структуры:

  1. Определите свой class, но вы хотите использовать обычный дизайн OO.
  2. Членские переменные вашего classа переходят в структуру языка C.
  3. В заголовочном файле вы не хотите раскрывать переменные-члены вашего объекта (поскольку они были бы «частными» на языке OO). Вместо этого используйте непрозрачный указатель, т.е.
    typedef struct mystruct_s *mystruct_t; // first argument to all your methods
  4. Для всех методов, которые вы хотите быть «общедоступными», поместите свои подписи в свой .h-файл. Органы метода должны войти в файл .c, а «частные» методы должны быть определены только в файле .c, а также объявлены статическими, чтобы их символы не сталкивались с символами, определенными в других файлах.

Умные соглашения об именах, такие как подчеркивания, не нужны с помощью этого метода, но это означает, что все ваши переменные-члены будут закрытыми. Функции могут быть общедоступными или частными, хотя публичные функции они являются частью глобального пространства имен, поэтому вы можете захотеть mystruct_push() их имена с именем «package», таким как mystruct_push() , mystruct_pop() и т. Д.

Вам также необходимо выяснить, отвечает ли вызывающий или библиотека за вызов malloc() и free() . Скорее всего, у вас будут mystruct_t *create() и void destroy(mystruct_t *target) .

Вы все еще можете думать, что объект ориентирован на C.

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

Что касается polymorphismа, вы можете передать размер структуры как первый член структуры, поэтому вы знаете, как ее отличать.

Здесь есть отличный pdf-ориентированный программный проект с ANSI-C .

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

Я обнаружил, что для того, чтобы научиться создавать объекты, лучше подумать о том, как они будут выглядеть для вызывающего. Тот же подход может помочь вам, идя в другую сторону. Посмотрите, как выглядит API для вашего компонента. Одним из хороших способов является изучение существующих C API (я использовал стандартные Java API как набор примеров OO API).

Вы привыкли использовать компонент очереди примерно так:

 import some.package.Queue; Queue q = new Queue(); q.add(item); 

В типичном C api вы ожидаете чего-то большего:

 #include  // provides queue, make_queue(), queue_add(), others queue q = make_queue(); // queue is probably a struct, or a struct* queue_add(q,item); 

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

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

Удачи!

Проверьте Lua C api . Это был мой путеводный свет до дизайна интерфейса C. Каждая функция принимает состояние Lua как ведущий аргумент, который становится вашим «этим». Наследование немного сложнее, но Chipmunk удается сделать довольно хорошую работу, раскрывая функции, которые занимают общие структуры фигур, и детализируют, какая функция фактически вызывается через «class». Вы часто можете использовать void *, чтобы функции выполняли разные типы (структуры) так, как вы перегружались в OO. Иногда он может чувствовать себя немного взломанным, но работает хорошо.

Первоначально C ++ был всего лишь компилятором, который написал код C из источников C ++; Затем они были скомпилированы с помощью встроенного компилятора C, связанного и т. д.

Следовательно, все методы ООП доступны в C – это просто то, что компилятор вам не поможет, и не предоставляет всех возможностей времени компиляции, таких как шаблоны, переопределения операторов, скрытие данных и т. Д.

  1. C ++ «struct» была (вероятно, до сих пор) эквивалентна «classу», при этом все члены «public».
  2. Функции-члены могут быть реализованы как указатели функций в структуре; это может обеспечить инкапсуляцию и polymorphism. Конструкторы существуют в глобальной области, если вы не используете фабрики. Деструкторы могут быть функциями-членами.
  3. Используя функции-члены доступа, такие как getColor () , setColor () может облегчить внутренние различия и обеспечить скрытие некоторых данных. Если вы действительно этого хотите, вы можете использовать предложение Брайана Бонди скрываться с макросами.
  4. На самом деле существует много библиотек FOSS, которые предоставляют стандартные контейнеры – hash-таблицы, динамические массивы, связанные списки и т. Д.

Я вторые предложения для того, чтобы сделать «Безумное ОО в С.» Я также думаю, что вам может понадобиться время, чтобы посмотреть, как работает OO Perl. В основном OO выполняется в Perl, когда интерпретатор предоставляет каждому методу экземпляр как неявный первый параметр. Вы захотите сделать то же самое в C, явным образом, и используйте действительно хорошую организацию кода, поскольку компилятор не обеспечит вас надежной инкапсуляцией.

Кстати, вы можете принудительно удерживать членов ваших структур конфиденциальными, используя непрозрачные указатели . Я, кажется, помню, что стандарты и рекомендации по программированию GNU включали в себя технику для этого, в основном отбрасывая все на void *, когда он был передан, а затем используя typedefs для обозначения каждого определенного типа непрозрачного указателя, который должен был быть передан. (т.е. каждый «class»)

Связанный Можете ли вы написать объектно-ориентированный код в C?

Вы можете делать производные classы также с помощью C:

Производные classы в C – Каков ваш любимый метод?

использовать glib, c библиотеку с oop http://library.gnome.org/devel/glib/2.20/

Давайте будем гением компьютера.