Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: C++ и ООП для микроконтроллеров AVR
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
Страницы: 1, 2
koluna
Здравствуйте!

Что вы думаете по поводу ООП для микроконтроллеров AVR на языке C++?

Благодарю заранее!
Tcom
Нравиться пишите на С++ для AVR.
tAmega
Смотря какой AVR, если 8 битные модели, то ООП это роскошь, и программировать на нем конечно можно, но по моему убеждениею неэффективно и громоздко.
Rst7
Цитата
и программировать на нем конечно можно, но по моему убеждениею неэффективно и громоздко.


Понимаете ли, многие не видят разницы между ООП, C++, STL и т.д. Конечно, темплейт типа vector уложит бедный AVR в могилу тут же. Некоторые фичи ООП имеет смысл применять для упрощения писанины - наглядный пример - устройство критической секции в ScmRTOS (хотя, лично мне больше нравится цикл for).

Часто полезна перегрузка операций - опять же, для уменьшения писанины.

Полновесная работа с объектами обычно упирается в ограниченность ресурсов. Хотя, есть любители, которые пользуют это дело во всю.
tAmega
Видел код на C++ для AVR, нашел единственное объяснение, для чего там был использован C++, это идеальный способ существенно запутать все что можно запутать.
Код был идеально красиво написан, со всеми отступами и пояснениями. Но понять что там наверчено удалось с 18й попытки. Такого иезуитского подхода я прежде не видел,
но взял на заметку, как именно надо путать следы, чтобы стать незаменимым для сопровождения данной конкретной программы.
Rst7
Цитата
нашел единственное объяснение, для чего там был использован C++, это идеальный способ существенно запутать все что можно запутать.


Думаете на Plain C нельзя запутать?
Код
main(O,_){for(_?--O,main(O+2,"?DKwhQH?b@`JD|?dA@TIT?qpEzR?hB@hTB?BHB@hTB"
"?Po@SdB?"[O]):5;O&&_>1;printf("%s",_-'?'?_&1?"||":" ":(_=0,"\n")),_/=2);}
DpInRock
Программирование в ООП обычно требует динамического выделения памяти.
Что является чистым идиотизмом в embedded. Ибо в автокомпьютере, которые управляет зажиганием не должно быть ситуаций - "не могу выделить память для объекта". А в этм случае динамическое выделение лишается какого-либо смысла. Значит его вполне заменяет статическое. (Т.е. динамическое выделение памяти не имеющее отказов в условиях конечной памяти - есть статическое выделение).
А это значит, что все объекты создаются заранее.
А в системе где все заранее определено я бы использовал ООП исключительно из-за личных пристрастий (к примеру, нравится так абстрагироваться).

Я, лично, сишному менеджеру кучи не доверяю и никогда не использую. Неужели я могу доверять механизмам ООП, которые скрыты еще сильнее?
Ембеддерская программа принципиально не должна содержать эксепшены.

Но я человек, который использует Си, как более удобный ассемблер (порок воспитания). Возможно, реальность - другая.
Rst7
Цитата
Программирование в ООП обычно требует динамического выделения памяти.
...
Я, лично, сишному менеджеру кучи не доверяю и никогда не использую.
...
Ембеддерская программа принципиально не должна содержать эксепшены.


Во-во. Смешались в кучу кони, люди... То, о чем я говорил.

Никакого отношения динамическое выделение памяти к ООП не имеет.

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

Эксепшены - это такая удобная форма goto. Или, даже longjmp, если быть точным.
kurtis
Цитата
Никакого отношения динамическое выделение памяти к ООП не имеет.

Дык если взять STL, то там куда не плюнь, везде динамическое выделение памяти, а без STL, С++ это скорее "Си с классами".
Rst7
Цитата
Дык если взять STL


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

Хотя, болтают всякое про то, что STL - составная часть C++... Но то дураки болтают smile.gif
_Pasha
Цитата(kurtis @ May 10 2009, 14:29) *
 С++ это скорее "Си с классами".

А ,пардон, этого мало для эмбеда? wink.gif
researcher
Об ООП хорошо думаю smile.gif, но в AVR ООП тесно.
Какая необходимость использовать ООП в AVR, когда есть С?

Цитата(n_bogoyavlensky @ May 10 2009, 08:21) *
Что вы думаете по поводу ООП для микроконтроллеров AVR на языке C++?
DpInRock
ОП имеет смысл когда есть что наследовать и есть кому.
Внутри одной законченной программы, которая никогда не будет иметь связей с другими программами эти все ситуации заранее определены.
А следовательно, физического смысла не имеют.

А городить ООП только из-за перегрузки функций, имхо - лишнее. Писанины все-таки больше.

ООП имеет сермяжный смысл для большой группы программ, которые как-то взаимодействуют. И ООП не столько способ исполнения программы, сколько способ ея написания. Т.е. фича для программиста. Некая парадигма существования.

А так, конечно, очень удобно, что в структуру можно нормальным и явным образом добавлять функции. Безусловно. Иногда очень удобно.
haker_fox
Цитата(DpInRock @ May 10 2009, 22:07) *
ОП имеет смысл когда есть что наследовать и есть кому.

К счастью, такие ситуации возникаю довольно часто. К счастью, потому что это не даст погубить ООП.
Цитата(DpInRock @ May 10 2009, 22:07) *
Внутри одной законченной программы, которая никогда не будет иметь связей с другими программами эти все ситуации заранее определены.
А следовательно, физического смысла не имеют.

Видимо многие несколько другого мнения, раз используют ООП, не имеющий физического смысла.
Цитата(DpInRock @ May 10 2009, 22:07) *
А городить ООП только из-за перегрузки функций, имхо - лишнее. Писанины все-таки больше.

Наверно писанины будет меньше, если городить нечто подобное на Plain C.
Цитата(DpInRock @ May 10 2009, 22:07) *
ООП имеет сермяжный смысл для большой группы программ, которые как-то взаимодействуют. И ООП не столько способ исполнения программы, сколько способ ея написания. Т.е. фича для программиста. Некая парадигма существования.

Без комментариев.
Цитата(DpInRock @ May 10 2009, 22:07) *
А так, конечно, очень удобно, что в структуру можно нормальным и явным образом добавлять функции. Безусловно. Иногда очень удобно.

Это тоже без комментариев.

Цитата(DpInRock @ May 10 2009, 19:56) *
Но я человек, который использует Си, как более удобный ассемблер (порок воспитания). Возможно, реальность - другая.

Вообще, как Вы можете говорить после этого о достатках и недостатках ООП?
Rst7
Цитата
Вообще, как Вы можете говорить после этого о достатках и недостатках ООП?


Ну я тоже обычно не пользую плюсы. Мне можно говорить о достоинствах и недостатках? Видимо можно, потому что я не стал отговаривать от их применения? wink.gif

Каждый должен выбрать себе собственный способ полоскания мозгов, и не стоит в этом людям мешать smile.gif
dxp
Мущщины! Вы бы сначала определились в терминах. smile.gif Что вы понимаете под ООП, например? (Hint: классы С++ как таковые - не ООП; шаблоны - не ООП; перегрузка операций - тоже не ООП; и еще много чего в С++ - не ООП smile.gif ).
Rst7
Цитата
классы С++ как таковые - не ООП;


Как это? Класс это и есть описание объекта. Со всеми понтами.
Непомнящий Евгений
Цитата(Rst7 @ May 11 2009, 13:35) *
Как это? Класс это и есть описание объекта. Со всеми понтами.


ООП - это программирование, когда программа представляет собой набор взаимодействующих объектов. Классы С++ - это некая усовершенствованная разновидность обычных С-шных струтур. Если вы пишете на plain C и используете структуры - совсем не факт, что у вас ОО-программа.


Цитата(n_bogoyavlensky @ May 10 2009, 10:21) *
Что вы думаете по поводу ООП для микроконтроллеров AVR на языке C++?


Солидарен с Tcom - нравится -пишите, не нравится - не пишите.
В ряде случаев, имхо, С++ сильно облегчает жизнь, причем без всякого оверхеда по сравнению с ручным кодированием того же на plain C. С другой стороны, он дает возможность писать в обычном C-стиле. Использовать ли STL, динамическую память, вирутальные функции, шаблоны - это исключительно ваш выбор...
Herz
Цитата(dxp @ May 11 2009, 11:29) *
Мущщины! Вы бы сначала определились в терминах. smile.gif Что вы понимаете под ООП, например? (Hint: классы С++ как таковые - не ООП; шаблоны - не ООП; перегрузка операций - тоже не ООП; и еще много чего в С++ - не ООП smile.gif ).

Я лично только одно: Организация Освобождения Палестины. biggrin.gif
Rst7
Цитата
ООП - это программирование, когда программа представляет собой набор взаимодействующих объектов.


Не возражаю, а вот дальше Вы неправы.

Цитата
Классы С++ - это некая усовершенствованная разновидность обычных С-шных струтур.


Это неверно. Тут материализм в чистом виде. Количество (усовершенствований) переходит в качество:

Цитата
Класс — это тип, описывающий устройство объектов. Понятие «класс» подразумевает некоторое поведение и способ представления. Понятие «объект» подразумевает нечто, что обладает определённым поведением и способом представления. Говорят, что объект — это экземпляр класса. Класс можно сравнить с чертежом, согласно которому создаются объекты. Обычно классы разрабатывают таким образом, чтобы их объекты соответствовали объектам предметной области.


Можно конечно пользовать классы как банальные структуры, но это не будет ООП. Класс - это и есть базовый примитив ООП. Без него, как описателя объектов, ООП не получится - нет нужного способа. Хотя, конечно, можно реализовать ООП средствами Plain C, но зачем?

В реальной жизни использование ООП приводит к бездумному раздуванию кода - объекты ради объектов, ради одного присваивания воротятся огромные иерархии. Вот против этого я выступаю весьма решительно. К сожалению, у профи часто эта болезнь протекает в наиболее острой форме sad.gif
dxp
Цитата(Rst7 @ May 11 2009, 16:35) *
Как это? Класс это и есть описание объекта. Со всеми понтами.

Класс - это тип, определяемый пользователем. Не более того. ООП - парадигма программирования, в основе которой лежит создание иерархии наследуемых типов с виртуальными функциями (методами), которая дает возможность использовать полиморфизм (в данном случае: переопределяемое на рантайме поведение). ООП начинает рулить там, где мы сразу (на уровне базового класса - родителя) знаем "что" мы хотим, но пока не знаем "как" это сделать. Это "как" будет известно на этапе определения классов-потомков - каждый потомок имеет свое собственное "как". И, построив такую иерархию, мы получаем возможность единообразно рулить разными объектами через интерфейс базового класса. Очень сильно экономит силы и время, когда применяется к месту. Например, даже простейший GUI - канонический пример, где рулит ООП.

Что касается накладных, то их там нет. Чтобы на том же С построить ту же функциональность, придется городить массивы указателей на функции, сами функции и т.п. Выйдет ровно то же самое. Только будет гора запутанного кода, и сделать ошибку там куда проще.

Классы как таковые можно использовать сами по себе, как пользовательские типы. Никто не заставляет использовать их только в ООП.

Шаблоны - это просто параметризованные типы, т.е. механизм создания классов по шаблону. К ООП относятся так же, как и классы.

Ну, а прочие средства С++, как перегрузка операторов, исключения, RTTI и др., - это просто всмомогательные средства языка.

Если все использовать с пониманием, то никакого оверхеда С++ по сравнению с С не дает, т.к. многие его средства - это абстракции уровня этапа компиляции.
demiurg_spb
Цитата(DpInRock @ May 10 2009, 17:07) *
А так, конечно, очень удобно, что в структуру можно нормальным и явным образом добавлять функции. Безусловно. Иногда очень удобно.
Это и в чистом СИ можно устроить через указатели и тоже явным образомsmile.gif. А вот шаблоны, идеология конструктор-деструктор, перегрузка, наследование, и ещё масса всего - это действительно удобно. Но всеми фичами СИ++ пользоваться на АВР нет возможности, а так-как я идеалист - то для меня нет смысла вообще. Да для программирования под конкретную ОС на ПК СИ++ действительно рулит. Ну и для мощных встраиваемых архитектур несомненно тоже.
Rst7
Цитата
Класс - это тип, определяемый пользователем.


И описывающий устройство объекта. Все остальные ООПшные пляски оперируют именно объектами. Я утверждаю, что класс - это базис ООП. Однако, если используя классы, не пользовать эти самые пляски, то классы превращаются в банальные структуры. И никакого ООП нет. Т.е. я не вижу смысла проводить различие между применением ООП и классов - если есть классы, но не пользуются методологии ООП, нет смысла говорить о классах - в этом случае они суть просто структуры данных. В этом состоит смысл моего недоуменного "Как это?", возможно, с точки зрения формальной логики и не совсем корректного.
dxp
Цитата(Rst7 @ May 11 2009, 18:52) *
Я утверждаю, что класс - это базис ООП.

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

Цитата(Rst7 @ May 11 2009, 18:52) *
Однако, если используя классы, не пользовать эти самые пляски, то классы превращаются в банальные структуры. И никакого ООП нет. Т.е. я не вижу смысла проводить различие между применением ООП и классов - если есть классы, но не пользуются методологии ООП, нет смысла говорить о классах - в этом случае они суть просто структуры данных. В этом состоит смысл моего недоуменного "Как это?", возможно, с точки зрения формальной логики и не совсем корректного.

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

  • конструировать себя, как надо пользователю, и грамотно удалять (если надо);
  • он скрывает представление (инкапсуляция, абстракция);
  • он может вводить новые операции на объектами своего типа (путем перегрузки операторов);
  • он, наконец, позволяет строить новые типы на базе существующих (наследование), но это тоже еще не ООП - без полиморфизма.

Поверьте, даже без ООП все эти перечисленные возможности - это очень немало и сильно помогают в софтописании. В том числе и под AVR. Т.к. совершенно не тянут никаких накладных расходов.
Rst7
Цитата
Объектно-ориентированные программы можно писать и без классов - даже на ассемблере. И так и делали, пока не появился более удобный для этого инструментарий.


Конечно. Но для этого необходимо сделать какой-то унифицированный способ описания объектов. Аля класс. Т.е. "тип, описывающий устройство объектов". Не путайте класс-ключевое_слово_плюсов и класс-понятие_ООП(тип, описывающий устройство объектов).

Цитата
Поверьте, даже без ООП все эти перечисленные возможности


Что-то разговор не о том. Топикстартер про использование ООП. А мы?

И вообще, чего Вы на меня напали? wink.gif Прочтите топик, разве я где-то утверждал про накладные расходы? Разве я отговаривал топикстартера от ООП?
SasaVitebsk
Цитата(DpInRock @ May 10 2009, 13:56) *
Программирование в ООП обычно требует динамического выделения памяти.
Что является чистым идиотизмом в embedded. Ибо в автокомпьютере, которые управляет зажиганием не должно быть ситуаций - "не могу выделить память для объекта". А в этм случае динамическое выделение лишается какого-либо смысла. Значит его вполне заменяет статическое. (Т.е. динамическое выделение памяти не имеющее отказов в условиях конечной памяти - есть статическое выделение).


И да и нет. Приведу простой пример:

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

Всё это прекрасно работает на AVR.

Это я не к ООП, а просто в отрицание что "динамическое выделение памяти ... является чистым идиотизмом в embedded".
dxp
Цитата(Rst7 @ May 11 2009, 21:46) *
И вообще, чего Вы на меня напали? wink.gif Прочтите топик, разве я где-то утверждал про накладные расходы? Разве я отговаривал топикстартера от ООП?

Да, что вы, я совсем не напал. smile.gif И не на вас - т.е. посты-то ко всем адресованы. Просто мне показалось, что народ считает, что ООП - это любые С++'ные фишки. Вот и постарался внести ясность.

За ООП, кстати, не агитирую - эта вещь хороша к месту, и пихать куда попало ее - наживать геморрой. А вот классы сами по себе штука универсальная, и их можно использовать практически без ограничений, в том числе и на AVR. (это тоже ко всем, не только к вам smile.gif ).
VladimirYU
Цитата(dxp @ May 12 2009, 08:03) *
За ООП, кстати, не агитирую - эта вещь хороша к месту, и пихать куда попало ее - наживать геморрой. А вот классы сами по себе штука универсальная, и их можно использовать практически без ограничений, в том числе и на AVR. (это тоже ко всем, не только к вам smile.gif ).

А я бы агитировал за ООП, в условиях корпоративной разработки проектов и их дальнейшего сопровождения альтернативы ООП ИМХО не вижу.
Rst7
Цитата
в условиях корпоративной разработки проектов


Окститесь. Корпоративная разработка для AVR? biggrin.gif
dxp
Цитата(VladimirYU @ May 12 2009, 13:54) *
А я бы агитировал за ООП, в условиях корпоративной разработки проектов и их дальнейшего сопровождения альтернативы ООП ИМХО не вижу.

Возможно, вы имели в виду объектное программирование? Т.е. использование классов/объектов? Или именно ООП?
VladimirYU
Цитата(dxp @ May 12 2009, 15:31) *
Возможно, вы имели в виду объектное программирование? Т.е. использование классов/объектов? Или именно ООП?

Я именно имел в виду объектно-ориентированный подход к проетированию пограммы, конечно с использованием классов. Но классоы это лишь инструмент. Для меня в свое время это была настоящая ломка перейти к идеологии ООП (с С на С++), но это сугубо личные впечатления. У нас в конторе было чуть ли не табу на использование ++ и ООП для программирования МК, пока мы с напарником за почти два года на собственных примерах (проектах) не сломали этот стереотип.
dxp
Цитата(VladimirYU @ May 12 2009, 18:45) *
Я именно имел в виду объектно-ориентированный подход к проетированию пограммы, конечно с использованием классов.

Хм, интересно... Ну, а вот на примере, скажем. Вот пусть есть дивайс, который выполняет какие-то функции: измеряет температуру на объекте, управляет нагревательным элементом, опрашивает органы управления (кнопки, энкодер и т.п.), выводит соответствующую индикацию, общается с терминалом и т.д. Вот где тут применить ООП?

Не, я понимаю, конечно, что "за уши" можно все притянуть - например, создать самый базовый класс TSomething, от него родить класс TInput, от которого родить классы TTempGauge, TButton, TEncoder, от TSomthing родить TOutput, от которого TIndicator и т.п. Но это как-то не выглядит адекватным и логичным, потому что нативной связи между всеми этими классами просто нет. И нет необходимости (да и возможности) рулить поведением объектов производных классов через интерфейс базового.

Вот просто создать классы, описывающие составные функциональные части проекта, - это да, правильно и логично. Тут есть смысл, и это даст эффект. Только это не ООП, а объектный подход.
koluna
Цитата(dxp @ May 11 2009, 13:29) *
Мущщины! Вы бы сначала определились в терминах. smile.gif Что вы понимаете под ООП, например? (Hint: классы С++ как таковые - не ООП; шаблоны - не ООП; перегрузка операций - тоже не ООП; и еще много чего в С++ - не ООП smile.gif ).


Под ООП я подразумеваю:
1. Инкапсуляцию.
2. Наследование.
3. Полиморфизм.
_Pasha
Цитата(n_bogoyavlensky @ May 12 2009, 21:24) *
Под ООП я подразумеваю:
1. Инкапсуляцию.

Приехали... и где на AVR инкапсуляция???
singlskv
Цитата(dxp @ May 12 2009, 17:40) *
Хм, интересно... Ну, а вот на примере, скажем. Вот пусть есть дивайс, который выполняет какие-то функции: измеряет температуру на объекте, управляет нагревательным элементом, опрашивает органы управления (кнопки, энкодер и т.п.), выводит соответствующую индикацию, общается с терминалом и т.д. Вот где тут применить ООП?
Не, я понимаю, конечно, что "за уши" можно все притянуть - например, создать самый базовый класс TSomething, от него родить класс

Ну на AVR конечно не просто, хотя...
Но вот на Sam7 OOП легко...
Допустим "главный" обмен данными ведется через протокол Modbus.
Ну и есть
1,2,3 Uart
1 USB(CDC, типа виртуальный USB-485 переходник прямо в девайсе)
1,2 CAN(мост Modbus <-> CAN)

У меня есть структура ModbusInterface и есть наследуемуе от нее структуры UsbInterface, Rs485Interface, итд...
В ModbusInterfect определена общая для всех интерфейсов функциональность, все остальное делается
через общие процедуры SendMessage(), ReceiveMessage(), итд

Так же каждый объект может быть мастером или слейвом.
Для всех интерфейсов общая функция таймаута на интерфейсах...

Это ООП ?

Но оно фсе написанно на чистом С... laughing.gif
dxp
Цитата(singlskv @ May 13 2009, 01:53) *
У меня есть структура ModbusInterface и есть наследуемуе от нее структуры UsbInterface, Rs485Interface, итд...
В ModbusInterfect определена общая для всех интерфейсов функциональность, все остальное делается
через общие процедуры SendMessage(), ReceiveMessage(), итд

Так же каждый объект может быть мастером или слейвом.
Для всех интерфейсов общая функция таймаута на интерфейсах...

Это ООП ?

Но оно фсе написанно на чистом С... laughing.gif

SendMessage(), ReceiveMessage() где определены? И если в ModbusInterface, то как реализовна подмена? И как выполняется наследование на чистом С?
777777
Цитата(_Pasha @ May 12 2009, 22:34) *
Приехали... и где на AVR инкапсуляция???

А где она на пентиуме? :-))))))
singlskv
Цитата(dxp @ May 13 2009, 07:24) *
SendMessage(), ReceiveMessage() где определены? И если в ModbusInterface, то как реализовна подмена?

Определены в ModbusInterface как указатели на функции.
Подмена в момент инициализации объекта.
Цитата
И как выполняется наследование на чистом С?

Первое поле в структуре потомка ModbusInterface, дальше свои оригинальные поля
ну и приведение типа в функциях ModbusTimeot, ModbusAutomat, итд...
dxp
Цитата(singlskv @ May 13 2009, 10:32) *
Определены в ModbusInterface как указатели на функции.
Подмена в момент инициализации объекта.

Первое поле в структуре потомка ModbusInterface, дальше свои оригинальные поля
ну и приведение типа в функциях ModbusTimeot, ModbusAutomat, итд...

Ну да, в таком виде похоже на ООП. smile.gif Только это "закат Солнца вручную". smile.gif Почему бы не использовать для этого более адекватные средства - писанины меньше, места для ошибок меньше, наглядности и элегантности больше. Тем более, что эти средства имеются под рукой в полном объеме.
singlskv
Цитата(dxp @ May 13 2009, 09:11) *
Ну да, в таком виде похоже на ООП. smile.gif Только это "закат Солнца вручную". smile.gif Почему бы не использовать для этого более адекватные средства - писанины меньше, места для ошибок меньше, наглядности и элегантности больше. Тем более, что эти средства имеются под рукой в полном объеме.

Просто довольно большой проект в котором ООП имеет смысл всего лишь в 2-3 местах,
часть кода моя часть других программистов, все написано на С,
мешать С с плюсами не хотелось.

Да и писанины не многим больше чем в плюсах, на самом OO подходе уже большая экономия для этой части.
А что касаемо ошибок, дык приведение типов всего один раз на функцию, а в остальном от плюсов мало в чем отличие.
dxp
Цитата(singlskv @ May 13 2009, 12:39) *
А что касаемо ошибок, дык приведение типов всего один раз на функцию, а в остальном от плюсов мало в чем отличие.


Еще забыли инициализацию руками (как указателей, так и полей самой базовой структуры, что делается автоматом в ++) в каждом объекте. Тут внимательность нужна - легко не то прописать. Особенно, когда что-то добавляешь/модифицируешь после заметного перерыва в работе над проектом. Писанины все-таки заметно больше - много деталей реализации, которые просто скрыты при использовании рассчитанных на это средств. Исходник больше загроможден "технологическими" деталями.


Что касается совместной работы, то это не пролема - свою часть держать в отдельных файлах, для взаимодействия с сишной частью написать интерфейс в виде extern "C" функций-оберток. Но вам виднее. smile.gif
singlskv
Цитата(dxp @ May 13 2009, 10:26) *
Еще забыли инициализацию руками (как указателей, так и полей самой базовой структуры, что делается автоматом в ++) в каждом объекте. Тут внимательность нужна - легко не то прописать. Особенно, когда что-то добавляешь/модифицируешь после заметного перерыва в работе над проектом.
Здесь я полность согласен с Вами, инициализация таки ручками...
Цитата
Писанины все-таки заметно больше - много деталей реализации, которые просто скрыты при использовании рассчитанных на это средств. Исходник больше загроможден "технологическими" деталями.
Кроме инициализации там практически нет "лишнего" кода.
Фишек типа присвоить одному объекту значение другого там просто нет за ненадобностью, да и перегрузки операторов нафиг не нужны,
а насчет "технологических" деталей, вот они как раз часто раздувают код в плюсах при неправильном использовании
Цитата
Что касается совместной работы, то это не пролема - свою часть держать в отдельных файлах, для взаимодействия с сишной частью написать интерфейс в виде extern "C" функций-оберток. Но вам виднее. smile.gif

В этом проекте связок другого кода с моим ООП кодом слишком много(так уж получилось исторически...),
поэтому делать обертки для всего просто не эфективно... потому что придется делать реальные обертки на вызовы коротких функций.
yanvasiij
Люди, поднял тему в связи с глубокой заинтересованностью. Только попытаюсь перенаправить диалог в несколько другое русло. Положим взвесив все "За" и "Против" я сделал выбор в пользу C++ на микроконтроллерах. Пусть даже без STL, как тут уже было сказано "Си с классами", ведь даже так это достаточно мощный инструмент. Мне интересен уже вопрос реализации. Вот, положим, есть задача: пусть мне надо собирать данные с датчиков, подключенных к шине CAN к моему устройству по протоколу CanOpen, обрабатывать эти данные и передавать скажем по GPRS открывая соединение с телнет сервером. По какой логике формировать классы и как создавать объекты? Как быть обработчиками прерываний?

Пока я рассуждаю так: в программе я создаю несколько классов: класс мастера протокола CANopen, он будет наследовать класс драйвера CAN, который будет уже привязан к железу; класс\сборщик данных с тензодатчиков, наследующий свойства класса протокола CANopen (раз уж датчики подключены к этой шине); класс тензодатчиков будет наследовать уже верхний класс приложения, которое по определенному алгоритму будет считывать эти данные, этот же класс будет наследовать класс для работы с GPRS модемом. Экземпляр этого то класса и будет создаваться в main() и он будет запускать в работу всё приложение.

У меня нет идей как быть с прерываниями, как их обработчики закладывать в классы драйверов? Как все это дело привязвать к RTOS? Вообщем буду очень признателен за любые комментарии по теме.
andrewlekar
Во-первых, ООП вы напрасно определяете через термины C++. Классическое определение: ООП - это объекты обменивающиеся сообщениями. Цитата из вики: Object-oriented programming (OOP) is a programming paradigm that represents the concept of "objects" that have data fields (attributes that describe the object) and associated procedures known as methods. Objects, which are usually instances of classes, are used to interact with one another to design applications and computer programs.
То, что предлагает C++ изрядно запутывает программистов. Я бы посоветовал сначала хорошо изучить Си, а потом уже потихоньку залезать в С++, если так хочется.

ТС рекомендую не углубляться в архитектуру наследования. Гораздо проще сделать так:
1. Выделить сущности в отдельные модули. Пускай датчик будет в отдельном модуле.
2. Если сущность бывает в единственном экземпляре, то можно оставить как есть - модуль с экспортируемыми функциями. Если вы большой любитель классов, то можно обернуть в синглтон.
3. Если сущность может существовать в нескольких экземплярах, то оборачивайте в класс. Например, датчиков может быть много - делаем класс датчиков.
4. Не заморачивайтесь с наследованием. Сделайте разные датчики копипастой. Когда всё заработает, одинаковый код можно вынести в базовый класс.
5. Чтобы единообразно обрабатывать разные датчики, можно сделать для них общий интерфейс. Когда у вас все датчики будут написаны, общий интерфейс написать будет тривиально.
6. Без динамической памяти писать будет больно. Поля в классах нужно инициализировать руками. Инкапсуляция работает хреново потому как приватные поля светятся в заголовках модулей. Подумайте ещё раз, надо ли вам это, потому что Си гораздо гуманее, чем С++.
yanvasiij
Цитата(andrewlekar @ May 19 2014, 11:32) *
Во-первых, ООП вы напрасно определяете через термины C++...


Спасибо за методику! А как быть с обработчиками прерываний? Вот я хочу сделать класс драйверов, как туда засунуть обработчик? И что значит "Поля в классах нужно инициализировать руками", можно на примере это пояснить, если не затруднит?

У меня есть работы на голых Сях под RTOS. Относительно хороший. О плюсах и минусах процедурного программирования я более-менее имею представление. Основной недостаток - продолжительное время разработки. Я хочу "на своей шкуре" испытать плюсы и минусы С++. И плюс, про который все твердят - он помогает использовать старый код вновь гораздо легче, чем просто Си. Это то я и хочу проверить.
andrewlekar
В scmRTOS посмотрите как обработчики сделаны. У меня опыта нет упихивания С++ в контроллер.

Цитата
И что значит "Поля в классах нужно инициализировать руками"

В Си вы пишете в module.c:
Код
static int data;


И эта переменная у вас будет инициализирована нулём.

В С++ вы пишете в module.h:
Код
class Module { private: int data;};


И эта переменная у вас инициализирована не будет.
doom13
Цитата(yanvasiij @ May 19 2014, 09:33) *
А как быть с обработчиками прерываний? Вот я хочу сделать класс драйверов, как туда засунуть обработчик?


Можно так:
Код
typedef void (*isr_func)(void* context);

class Driver
{
    public:
        ...
        void InitIsr(isr_func isr);
        ...
};

class Device
{
    private:
        Device()
        {
            ...
            driver->InitIsr(Isr);
            ...        
        }
        
        ...
        static void Isr(void* context);
        Driver *driver;
        ...
};

yanvasiij
Цитата(andrewlekar @ May 19 2014, 13:00) *
В С++ вы пишете в module.h:
Код
class Module { private: int data;};


И эта переменная у вас инициализирована не будет.


Ну я так понимаю на то конструкторы и есть. Мне вот только не совсем понятно: можно ли объявлять объект - не создавать его динамически. То есть в приведенном Вами примере создание объекта вот так:
Код
class Module { private: int data;};

Module myModule;

int main (void)
{
    myModule.data=100500;
    while(1)
...
}


Цитата(doom13 @ May 19 2014, 13:22) *
Можно так:
...

Не совсем понял: Вы передали указатель на функцию обработчик прерывания в метод InitIsr?
andrewlekar
Цитата
можно ли объявлять объект - не создавать его динамически.

Можно. Только в вашем примере data будет недоступен.
doom13
Цитата(yanvasiij @ May 19 2014, 11:15) *
Не совсем понял: Вы передали указатель на функцию обработчик прерывания в метод InitIsr?

Теперь для каждого объекта можно задать свой обработчик прерывания, Ваши предложения...
Моя практика показала, что если обработчик прерывания - член класса, то он должен быть статик, или не работает. Т.о. это выбрано для реализации возможности задать собственный обработчик прерывания для каждого объекта.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.