|
C++ и ООП для микроконтроллеров AVR |
|
|
|
 |
Ответов
(1 - 67)
|
May 10 2009, 07:44
|

Йа моск ;)
     
Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610

|
Цитата и программировать на нем конечно можно, но по моему убеждениею неэффективно и громоздко. Понимаете ли, многие не видят разницы между ООП, C++, STL и т.д. Конечно, темплейт типа vector уложит бедный AVR в могилу тут же. Некоторые фичи ООП имеет смысл применять для упрощения писанины - наглядный пример - устройство критической секции в ScmRTOS (хотя, лично мне больше нравится цикл for). Часто полезна перегрузка операций - опять же, для уменьшения писанины. Полновесная работа с объектами обычно упирается в ограниченность ресурсов. Хотя, есть любители, которые пользуют это дело во всю.
--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
|
|
|
|
|
May 10 2009, 09:10
|

Йа моск ;)
     
Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610

|
Цитата нашел единственное объяснение, для чего там был использован 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);}
--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
|
|
|
|
|
May 10 2009, 10:56
|

Гуру
     
Группа: Участник
Сообщений: 2 254
Регистрация: 4-05-07
Из: Moscow
Пользователь №: 27 515

|
Программирование в ООП обычно требует динамического выделения памяти. Что является чистым идиотизмом в embedded. Ибо в автокомпьютере, которые управляет зажиганием не должно быть ситуаций - "не могу выделить память для объекта". А в этм случае динамическое выделение лишается какого-либо смысла. Значит его вполне заменяет статическое. (Т.е. динамическое выделение памяти не имеющее отказов в условиях конечной памяти - есть статическое выделение). А это значит, что все объекты создаются заранее. А в системе где все заранее определено я бы использовал ООП исключительно из-за личных пристрастий (к примеру, нравится так абстрагироваться).
Я, лично, сишному менеджеру кучи не доверяю и никогда не использую. Неужели я могу доверять механизмам ООП, которые скрыты еще сильнее? Ембеддерская программа принципиально не должна содержать эксепшены.
Но я человек, который использует Си, как более удобный ассемблер (порок воспитания). Возможно, реальность - другая.
--------------------
On the road again (Canned Heat)
|
|
|
|
|
May 10 2009, 11:13
|

Йа моск ;)
     
Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610

|
Цитата Программирование в ООП обычно требует динамического выделения памяти. ... Я, лично, сишному менеджеру кучи не доверяю и никогда не использую. ... Ембеддерская программа принципиально не должна содержать эксепшены. Во-во. Смешались в кучу кони, люди... То, о чем я говорил. Никакого отношения динамическое выделение памяти к ООП не имеет. Нет такого понятия - "сишный менеджер кучи". Может быть - менеджер кучи в составе библиотек, поставляемых с каким-либо компилятором. Эксепшены - это такая удобная форма goto. Или, даже longjmp, если быть точным.
--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
|
|
|
|
|
May 10 2009, 11:29
|
Местный
  
Группа: Свой
Сообщений: 466
Регистрация: 21-06-05
Пользователь №: 6 205

|
Цитата Никакого отношения динамическое выделение памяти к ООП не имеет. Дык если взять STL, то там куда не плюнь, везде динамическое выделение памяти, а без STL, С++ это скорее "Си с классами".
|
|
|
|
|
May 10 2009, 12:45
|

Частый гость
 
Группа: Свой
Сообщений: 135
Регистрация: 20-01-07
Из: Одесса – Харьков
Пользователь №: 24 616

|
Об ООП хорошо думаю  , но в AVR ООП тесно. Какая необходимость использовать ООП в AVR, когда есть С? Цитата(n_bogoyavlensky @ May 10 2009, 08:21)  Что вы думаете по поводу ООП для микроконтроллеров AVR на языке C++?
--------------------
:) Иду по жизни с паяльником ……………………
|
|
|
|
|
May 11 2009, 00:04
|

Познающий...
     
Группа: Свой
Сообщений: 2 963
Регистрация: 1-09-05
Из: г. Иркутск
Пользователь №: 8 125

|
Цитата(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)  Но я человек, который использует Си, как более удобный ассемблер (порок воспитания). Возможно, реальность - другая. Вообще, как Вы можете говорить после этого о достатках и недостатках ООП?
--------------------
Выбор.
|
|
|
|
|
May 11 2009, 10:35
|
Знающий
   
Группа: Свой
Сообщений: 771
Регистрация: 16-07-07
Из: Волгодонск
Пользователь №: 29 153

|
Цитата(Rst7 @ May 11 2009, 13:35)  Как это? Класс это и есть описание объекта. Со всеми понтами. ООП - это программирование, когда программа представляет собой набор взаимодействующих объектов. Классы С++ - это некая усовершенствованная разновидность обычных С-шных струтур. Если вы пишете на plain C и используете структуры - совсем не факт, что у вас ОО-программа. Цитата(n_bogoyavlensky @ May 10 2009, 10:21)  Что вы думаете по поводу ООП для микроконтроллеров AVR на языке C++? Солидарен с Tcom - нравится -пишите, не нравится - не пишите. В ряде случаев, имхо, С++ сильно облегчает жизнь, причем без всякого оверхеда по сравнению с ручным кодированием того же на plain C. С другой стороны, он дает возможность писать в обычном C-стиле. Использовать ли STL, динамическую память, вирутальные функции, шаблоны - это исключительно ваш выбор...
|
|
|
|
|
May 11 2009, 10:57
|

Йа моск ;)
     
Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610

|
Цитата ООП - это программирование, когда программа представляет собой набор взаимодействующих объектов. Не возражаю, а вот дальше Вы неправы. Цитата Классы С++ - это некая усовершенствованная разновидность обычных С-шных струтур. Это неверно. Тут материализм в чистом виде. Количество (усовершенствований) переходит в качество: Цитата Класс — это тип, описывающий устройство объектов. Понятие «класс» подразумевает некоторое поведение и способ представления. Понятие «объект» подразумевает нечто, что обладает определённым поведением и способом представления. Говорят, что объект — это экземпляр класса. Класс можно сравнить с чертежом, согласно которому создаются объекты. Обычно классы разрабатывают таким образом, чтобы их объекты соответствовали объектам предметной области. Можно конечно пользовать классы как банальные структуры, но это не будет ООП. Класс - это и есть базовый примитив ООП. Без него, как описателя объектов, ООП не получится - нет нужного способа. Хотя, конечно, можно реализовать ООП средствами Plain C, но зачем? В реальной жизни использование ООП приводит к бездумному раздуванию кода - объекты ради объектов, ради одного присваивания воротятся огромные иерархии. Вот против этого я выступаю весьма решительно. К сожалению, у профи часто эта болезнь протекает в наиболее острой форме
--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
|
|
|
|
|
May 11 2009, 11:12
|

Adept
     
Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343

|
Цитата(Rst7 @ May 11 2009, 16:35)  Как это? Класс это и есть описание объекта. Со всеми понтами. Класс - это тип, определяемый пользователем. Не более того. ООП - парадигма программирования, в основе которой лежит создание иерархии наследуемых типов с виртуальными функциями (методами), которая дает возможность использовать полиморфизм (в данном случае: переопределяемое на рантайме поведение). ООП начинает рулить там, где мы сразу (на уровне базового класса - родителя) знаем "что" мы хотим, но пока не знаем "как" это сделать. Это "как" будет известно на этапе определения классов-потомков - каждый потомок имеет свое собственное "как". И, построив такую иерархию, мы получаем возможность единообразно рулить разными объектами через интерфейс базового класса. Очень сильно экономит силы и время, когда применяется к месту. Например, даже простейший GUI - канонический пример, где рулит ООП. Что касается накладных, то их там нет. Чтобы на том же С построить ту же функциональность, придется городить массивы указателей на функции, сами функции и т.п. Выйдет ровно то же самое. Только будет гора запутанного кода, и сделать ошибку там куда проще. Классы как таковые можно использовать сами по себе, как пользовательские типы. Никто не заставляет использовать их только в ООП. Шаблоны - это просто параметризованные типы, т.е. механизм создания классов по шаблону. К ООП относятся так же, как и классы. Ну, а прочие средства С++, как перегрузка операторов, исключения, RTTI и др., - это просто всмомогательные средства языка. Если все использовать с пониманием, то никакого оверхеда С++ по сравнению с С не дает, т.к. многие его средства - это абстракции уровня этапа компиляции.
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
May 11 2009, 11:13
|

неотягощённый злом
     
Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643

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

Йа моск ;)
     
Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610

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

Adept
     
Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343

|
Цитата(Rst7 @ May 11 2009, 18:52)  Я утверждаю, что класс - это базис ООП. Зря. Объектно-ориентированные программы можно писать и без классов - даже на ассемблере. И так и делали, пока не появился более удобный для этого инструментарий. Цитата(Rst7 @ May 11 2009, 18:52)  Однако, если используя классы, не пользовать эти самые пляски, то классы превращаются в банальные структуры. И никакого ООП нет. Т.е. я не вижу смысла проводить различие между применением ООП и классов - если есть классы, но не пользуются методологии ООП, нет смысла говорить о классах - в этом случае они суть просто структуры данных. В этом состоит смысл моего недоуменного "Как это?", возможно, с точки зрения формальной логики и не совсем корректного. Нет, классы - это далеко не структуры. Структура (если речь идет о сишной структуре) - это просто агрегатный тип, содержащий в себе один и более других типов. А класс - это тип, определяемый пользователем. Этот тип обладает законченностью - он умеет: - конструировать себя, как надо пользователю, и грамотно удалять (если надо);
- он скрывает представление (инкапсуляция, абстракция);
- он может вводить новые операции на объектами своего типа (путем перегрузки операторов);
- он, наконец, позволяет строить новые типы на базе существующих (наследование), но это тоже еще не ООП - без полиморфизма.
Поверьте, даже без ООП все эти перечисленные возможности - это очень немало и сильно помогают в софтописании. В том числе и под AVR. Т.к. совершенно не тянут никаких накладных расходов.
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
May 11 2009, 14:46
|

Йа моск ;)
     
Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610

|
Цитата Объектно-ориентированные программы можно писать и без классов - даже на ассемблере. И так и делали, пока не появился более удобный для этого инструментарий. Конечно. Но для этого необходимо сделать какой-то унифицированный способ описания объектов. Аля класс. Т.е. "тип, описывающий устройство объектов". Не путайте класс-ключевое_слово_плюсов и класс-понятие_ООП(тип, описывающий устройство объектов). Цитата Поверьте, даже без ООП все эти перечисленные возможности Что-то разговор не о том. Топикстартер про использование ООП. А мы? И вообще, чего Вы на меня напали?  Прочтите топик, разве я где-то утверждал про накладные расходы? Разве я отговаривал топикстартера от ООП?
--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
|
|
|
|
|
May 11 2009, 21:38
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Цитата(DpInRock @ May 10 2009, 13:56)  Программирование в ООП обычно требует динамического выделения памяти. Что является чистым идиотизмом в embedded. Ибо в автокомпьютере, которые управляет зажиганием не должно быть ситуаций - "не могу выделить память для объекта". А в этм случае динамическое выделение лишается какого-либо смысла. Значит его вполне заменяет статическое. (Т.е. динамическое выделение памяти не имеющее отказов в условиях конечной памяти - есть статическое выделение). И да и нет. Приведу простой пример: Устройство связано с компом по RS485 интерфейсу. По этому интерфейсу поступают команды под них выделяется память динамически. Объекты разных размеров и на этапе написания длина их неизвестна. При нехватке памяти - никакого краха не происходит. Просто приостанавливается подгрузка, до момента разгрузки памяти по мере исполнения команд. Всё это прекрасно работает на AVR. Это я не к ООП, а просто в отрицание что "динамическое выделение памяти ... является чистым идиотизмом в embedded".
|
|
|
|
|
May 12 2009, 04:03
|

Adept
     
Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343

|
Цитата(Rst7 @ May 11 2009, 21:46)  И вообще, чего Вы на меня напали?  Прочтите топик, разве я где-то утверждал про накладные расходы? Разве я отговаривал топикстартера от ООП? Да, что вы, я совсем не напал.  И не на вас - т.е. посты-то ко всем адресованы. Просто мне показалось, что народ считает, что ООП - это любые С++'ные фишки. Вот и постарался внести ясность. За ООП, кстати, не агитирую - эта вещь хороша к месту, и пихать куда попало ее - наживать геморрой. А вот классы сами по себе штука универсальная, и их можно использовать практически без ограничений, в том числе и на AVR. (это тоже ко всем, не только к вам  ).
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
May 12 2009, 06:54
|
Местный
  
Группа: Свой
Сообщений: 426
Регистрация: 5-04-07
Из: Санкт-Петербург
Пользователь №: 26 782

|
Цитата(dxp @ May 12 2009, 08:03)  За ООП, кстати, не агитирую - эта вещь хороша к месту, и пихать куда попало ее - наживать геморрой. А вот классы сами по себе штука универсальная, и их можно использовать практически без ограничений, в том числе и на AVR. (это тоже ко всем, не только к вам  ). А я бы агитировал за ООП, в условиях корпоративной разработки проектов и их дальнейшего сопровождения альтернативы ООП ИМХО не вижу.
|
|
|
|
|
May 12 2009, 11:45
|
Местный
  
Группа: Свой
Сообщений: 426
Регистрация: 5-04-07
Из: Санкт-Петербург
Пользователь №: 26 782

|
Цитата(dxp @ May 12 2009, 15:31)  Возможно, вы имели в виду объектное программирование? Т.е. использование классов/объектов? Или именно ООП? Я именно имел в виду объектно-ориентированный подход к проетированию пограммы, конечно с использованием классов. Но классоы это лишь инструмент. Для меня в свое время это была настоящая ломка перейти к идеологии ООП (с С на С++), но это сугубо личные впечатления. У нас в конторе было чуть ли не табу на использование ++ и ООП для программирования МК, пока мы с напарником за почти два года на собственных примерах (проектах) не сломали этот стереотип.
|
|
|
|
|
May 12 2009, 13:40
|

Adept
     
Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343

|
Цитата(VladimirYU @ May 12 2009, 18:45)  Я именно имел в виду объектно-ориентированный подход к проетированию пограммы, конечно с использованием классов. Хм, интересно... Ну, а вот на примере, скажем. Вот пусть есть дивайс, который выполняет какие-то функции: измеряет температуру на объекте, управляет нагревательным элементом, опрашивает органы управления (кнопки, энкодер и т.п.), выводит соответствующую индикацию, общается с терминалом и т.д. Вот где тут применить ООП? Не, я понимаю, конечно, что "за уши" можно все притянуть - например, создать самый базовый класс TSomething, от него родить класс TInput, от которого родить классы TTempGauge, TButton, TEncoder, от TSomthing родить TOutput, от которого TIndicator и т.п. Но это как-то не выглядит адекватным и логичным, потому что нативной связи между всеми этими классами просто нет. И нет необходимости (да и возможности) рулить поведением объектов производных классов через интерфейс базового. Вот просто создать классы, описывающие составные функциональные части проекта, - это да, правильно и логично. Тут есть смысл, и это даст эффект. Только это не ООП, а объектный подход.
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
May 12 2009, 18:24
|
Профессионал
    
Группа: Участник
Сообщений: 1 040
Регистрация: 3-01-07
Пользователь №: 24 061

|
Цитата(dxp @ May 11 2009, 13:29)  Мущщины! Вы бы сначала определились в терминах.  Что вы понимаете под ООП, например? (Hint: классы С++ как таковые - не ООП; шаблоны - не ООП; перегрузка операций - тоже не ООП; и еще много чего в С++ - не ООП  ). Под ООП я подразумеваю: 1. Инкапсуляцию. 2. Наследование. 3. Полиморфизм.
--------------------
Благодарю заранее!
|
|
|
|
|
May 12 2009, 18:53
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(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(), итд Так же каждый объект может быть мастером или слейвом. Для всех интерфейсов общая функция таймаута на интерфейсах... Это ООП ? Но оно фсе написанно на чистом С...
|
|
|
|
|
May 13 2009, 03:24
|

Adept
     
Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343

|
Цитата(singlskv @ May 13 2009, 01:53)  У меня есть структура ModbusInterface и есть наследуемуе от нее структуры UsbInterface, Rs485Interface, итд... В ModbusInterfect определена общая для всех интерфейсов функциональность, все остальное делается через общие процедуры SendMessage(), ReceiveMessage(), итд Так же каждый объект может быть мастером или слейвом. Для всех интерфейсов общая функция таймаута на интерфейсах... Это ООП ? Но оно фсе написанно на чистом С...  SendMessage(), ReceiveMessage() где определены? И если в ModbusInterface, то как реализовна подмена? И как выполняется наследование на чистом С?
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
May 13 2009, 04:32
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(dxp @ May 13 2009, 07:24)  SendMessage(), ReceiveMessage() где определены? И если в ModbusInterface, то как реализовна подмена? Определены в ModbusInterface как указатели на функции. Подмена в момент инициализации объекта. Цитата И как выполняется наследование на чистом С? Первое поле в структуре потомка ModbusInterface, дальше свои оригинальные поля ну и приведение типа в функциях ModbusTimeot, ModbusAutomat, итд...
|
|
|
|
|
May 13 2009, 05:11
|

Adept
     
Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343

|
Цитата(singlskv @ May 13 2009, 10:32)  Определены в ModbusInterface как указатели на функции. Подмена в момент инициализации объекта.
Первое поле в структуре потомка ModbusInterface, дальше свои оригинальные поля ну и приведение типа в функциях ModbusTimeot, ModbusAutomat, итд... Ну да, в таком виде похоже на ООП.  Только это "закат Солнца вручную".  Почему бы не использовать для этого более адекватные средства - писанины меньше, места для ошибок меньше, наглядности и элегантности больше. Тем более, что эти средства имеются под рукой в полном объеме.
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
May 13 2009, 05:39
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(dxp @ May 13 2009, 09:11)  Ну да, в таком виде похоже на ООП.  Только это "закат Солнца вручную".  Почему бы не использовать для этого более адекватные средства - писанины меньше, места для ошибок меньше, наглядности и элегантности больше. Тем более, что эти средства имеются под рукой в полном объеме. Просто довольно большой проект в котором ООП имеет смысл всего лишь в 2-3 местах, часть кода моя часть других программистов, все написано на С, мешать С с плюсами не хотелось. Да и писанины не многим больше чем в плюсах, на самом OO подходе уже большая экономия для этой части. А что касаемо ошибок, дык приведение типов всего один раз на функцию, а в остальном от плюсов мало в чем отличие.
|
|
|
|
|
May 13 2009, 06:26
|

Adept
     
Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343

|
Цитата(singlskv @ May 13 2009, 12:39)  А что касаемо ошибок, дык приведение типов всего один раз на функцию, а в остальном от плюсов мало в чем отличие. Еще забыли инициализацию руками (как указателей, так и полей самой базовой структуры, что делается автоматом в ++) в каждом объекте. Тут внимательность нужна - легко не то прописать. Особенно, когда что-то добавляешь/модифицируешь после заметного перерыва в работе над проектом. Писанины все-таки заметно больше - много деталей реализации, которые просто скрыты при использовании рассчитанных на это средств. Исходник больше загроможден "технологическими" деталями. Что касается совместной работы, то это не пролема - свою часть держать в отдельных файлах, для взаимодействия с сишной частью написать интерфейс в виде extern "C" функций-оберток. Но вам виднее.
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
May 13 2009, 15:41
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(dxp @ May 13 2009, 10:26)  Еще забыли инициализацию руками (как указателей, так и полей самой базовой структуры, что делается автоматом в ++) в каждом объекте. Тут внимательность нужна - легко не то прописать. Особенно, когда что-то добавляешь/модифицируешь после заметного перерыва в работе над проектом. Здесь я полность согласен с Вами, инициализация таки ручками... Цитата Писанины все-таки заметно больше - много деталей реализации, которые просто скрыты при использовании рассчитанных на это средств. Исходник больше загроможден "технологическими" деталями. Кроме инициализации там практически нет "лишнего" кода. Фишек типа присвоить одному объекту значение другого там просто нет за ненадобностью, да и перегрузки операторов нафиг не нужны, а насчет "технологических" деталей, вот они как раз часто раздувают код в плюсах при неправильном использовании Цитата Что касается совместной работы, то это не пролема - свою часть держать в отдельных файлах, для взаимодействия с сишной частью написать интерфейс в виде extern "C" функций-оберток. Но вам виднее.  В этом проекте связок другого кода с моим ООП кодом слишком много(так уж получилось исторически...), поэтому делать обертки для всего просто не эфективно... потому что придется делать реальные обертки на вызовы коротких функций.
|
|
|
|
|
May 19 2014, 00:34
|
Местный
  
Группа: Свой
Сообщений: 321
Регистрация: 23-12-11
Из: Уфа
Пользователь №: 69 041

|
Люди, поднял тему в связи с глубокой заинтересованностью. Только попытаюсь перенаправить диалог в несколько другое русло. Положим взвесив все "За" и "Против" я сделал выбор в пользу C++ на микроконтроллерах. Пусть даже без STL, как тут уже было сказано "Си с классами", ведь даже так это достаточно мощный инструмент. Мне интересен уже вопрос реализации. Вот, положим, есть задача: пусть мне надо собирать данные с датчиков, подключенных к шине CAN к моему устройству по протоколу CanOpen, обрабатывать эти данные и передавать скажем по GPRS открывая соединение с телнет сервером. По какой логике формировать классы и как создавать объекты? Как быть обработчиками прерываний?
Пока я рассуждаю так: в программе я создаю несколько классов: класс мастера протокола CANopen, он будет наследовать класс драйвера CAN, который будет уже привязан к железу; класс\сборщик данных с тензодатчиков, наследующий свойства класса протокола CANopen (раз уж датчики подключены к этой шине); класс тензодатчиков будет наследовать уже верхний класс приложения, которое по определенному алгоритму будет считывать эти данные, этот же класс будет наследовать класс для работы с GPRS модемом. Экземпляр этого то класса и будет создаваться в main() и он будет запускать в работу всё приложение.
У меня нет идей как быть с прерываниями, как их обработчики закладывать в классы драйверов? Как все это дело привязвать к RTOS? Вообщем буду очень признателен за любые комментарии по теме.
|
|
|
|
|
May 19 2014, 01:22
|
Знающий
   
Группа: Участник
Сообщений: 837
Регистрация: 8-02-07
Пользователь №: 25 163

|
Во-первых, ООП вы напрасно определяете через термины 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. Без динамической памяти писать будет больно. Поля в классах нужно инициализировать руками. Инкапсуляция работает хреново потому как приватные поля светятся в заголовках модулей. Подумайте ещё раз, надо ли вам это, потому что Си гораздо гуманее, чем С++.
|
|
|
|
|
May 19 2014, 02:23
|
Местный
  
Группа: Свой
Сообщений: 321
Регистрация: 23-12-11
Из: Уфа
Пользователь №: 69 041

|
Цитата(andrewlekar @ May 19 2014, 11:32)  Во-первых, ООП вы напрасно определяете через термины C++... Спасибо за методику! А как быть с обработчиками прерываний? Вот я хочу сделать класс драйверов, как туда засунуть обработчик? И что значит "Поля в классах нужно инициализировать руками", можно на примере это пояснить, если не затруднит? У меня есть работы на голых Сях под RTOS. Относительно хороший. О плюсах и минусах процедурного программирования я более-менее имею представление. Основной недостаток - продолжительное время разработки. Я хочу "на своей шкуре" испытать плюсы и минусы С++. И плюс, про который все твердят - он помогает использовать старый код вновь гораздо легче, чем просто Си. Это то я и хочу проверить.
|
|
|
|
|
May 19 2014, 02:50
|
Знающий
   
Группа: Участник
Сообщений: 837
Регистрация: 8-02-07
Пользователь №: 25 163

|
В scmRTOS посмотрите как обработчики сделаны. У меня опыта нет упихивания С++ в контроллер. Цитата И что значит "Поля в классах нужно инициализировать руками" В Си вы пишете в module.c: Код static int data; И эта переменная у вас будет инициализирована нулём. В С++ вы пишете в module.h: Код class Module { private: int data;}; И эта переменная у вас инициализирована не будет.
Сообщение отредактировал andrewlekar - May 19 2014, 02:51
|
|
|
|
|
May 19 2014, 03:12
|
Профессионал
    
Группа: Свой
Сообщений: 1 404
Регистрация: 11-03-11
Из: Минск, Беларусь
Пользователь №: 63 539

|
Цитата(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; ... };
|
|
|
|
|
May 19 2014, 04:05
|
Местный
  
Группа: Свой
Сообщений: 321
Регистрация: 23-12-11
Из: Уфа
Пользователь №: 69 041

|
Цитата(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?
|
|
|
|
|
May 19 2014, 04:25
|
Знающий
   
Группа: Участник
Сообщений: 837
Регистрация: 8-02-07
Пользователь №: 25 163

|
Цитата можно ли объявлять объект - не создавать его динамически. Можно. Только в вашем примере data будет недоступен.
|
|
|
|
|
May 19 2014, 05:09
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(doom13 @ May 19 2014, 12:08)  Ваши предложения... Код class driver { public: void isr_handler(); .... };
driver Device1;
ISR(XXXX_vect) { Device1.isr_handler(); };
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
May 19 2014, 05:14
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(megajohn @ May 19 2014, 12:12)  и помнится, для реализации virtual нужно дополнительно место в RAM для каких-то таблиц ( давно где-то читал, но proof не дам - не знаю где читал ) Таблица в количестве одной штуки на каждый класс с виртуальными функциями. Обычно хранится в памяти кода (avr-gcc до сих пор этого не умеет, хранит в ОЗУ). В каждом объекте такого класса один указатель (уже в ОЗУ) на эту таблицу. Таблица состоит из указателей на реализации виртуальных функций, т.е. если класс имеет одну виртуальную функцию, то таблица состоит из одного указателя. Примерно так, "на пальцах".
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
May 19 2014, 07:48
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(doom13 @ May 19 2014, 13:13)  В таком исполнении ISR() нельзя сделать членом какого-то класса. А зачем ему быть членом класса? Оно даже логически слабо в класс просится. Членом класса является isr_handler(). Допустим у вас 4 UARTa: класс - один, объектов - 4, вектора прерываний для каждого объекта свои и каждый вектор вызывает один и тот же обработчик но для своего, конкретного объекта. С натяжкой можно было бы согласиться спрятать ISR внутрь класса для периферии, которая на кристалле одна. Но где гарантия, что завтра не придется переносить этот код на кристалл, у которого этой периферии две или три?
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
May 19 2014, 08:36
|
Профессионал
    
Группа: Свой
Сообщений: 1 404
Регистрация: 11-03-11
Из: Минск, Беларусь
Пользователь №: 63 539

|
Цитата(Сергей Борщ @ May 19 2014, 14:58)  А зачем ему быть членом класса? Оно даже логически слабо в класс просится. Членом класса является isr_handler(). Допустим у вас 4 UARTa: класс - один, объектов - 4, вектора прерываний для каждого объекта свои и каждый вектор вызывает один и тот же обработчик но для своего, конкретного объекта. С натяжкой можно было бы согласиться спрятать ISR внутрь класса для периферии, которая на кристалле одна. Но где гарантия, что завтра не придется переносить этот код на кристалл, у которого этой периферии две или три? Для каждого объекта, естественно, свой обработчик, его и задаём при помощи InitIsr (RegisterIsr если нравится). Хорошо, но допустим есть какой-то класс Device, у него есть интерфейс управления (class Spi), интерфейс передачи данных (class Uart), системный счётчик (class Timer), для каждого необходимо задать обработчик прерывания. Ну а обработчик прерывания логически просится в класс Device, т.к. он непосредственно и выполняет операции необходимые для функционирования Device. Допустим в системе пять таймеров, для каждого нужен свой обработчик. Логично всё "одинаковое" запихнуть внутрь класса, обработчик, который может отличаться для каждого таймера реализовать как callback-функцию.
|
|
|
|
|
May 19 2014, 09:01
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(doom13 @ May 19 2014, 15:46)  Допустим в системе пять таймеров, для каждого нужен свой обработчик. Угу. И каждый имеет свой вектор прерывания ISR(Timer_XX_vect) Как все пять обработчиков сделать статическими членами класса timer? Или я чего-то не понял в вашей идеологии? Цитата(doom13 @ May 19 2014, 15:46)  Логично всё "одинаковое" запихнуть внутрь класса, обработчик, который может отличаться для каждого таймера реализовать как callback-функцию. Угу, как callback или как виртуальную функцию. Или построить наследников на шаблонах используя Curiously recurring template pattern (я так думаю, сам не пробовал пока).
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
May 19 2014, 09:17
|
Профессионал
    
Группа: Свой
Сообщений: 1 404
Регистрация: 11-03-11
Из: Минск, Беларусь
Пользователь №: 63 539

|
Цитата(Сергей Борщ @ May 19 2014, 16:11)  Угу. И каждый имеет свой вектор прерывания ISR(Timer_XX_vect) Как все пять обработчиков сделать статическими членами класса timer? Или я чего-то не понял в вашей идеологии? Все пять обработчиков и не являются статическими членами класса Timer. У Timer есть только функция регистрации прерывания. Обработчик прерывания необходимо зарегистрировать после создания объекта. Цитата(Сергей Борщ @ May 19 2014, 16:11)  Угу, как callback или как виртуальную функцию. Или построить наследников на шаблонах используя Curiously recurring template pattern (я так думаю, сам не пробовал пока). Тут не понял иронию, что не так в моей реализации? Всё работает и , по-идее, нет никаких противоречий. Можно и унаследовать если есть желание.
|
|
|
|
|
May 19 2014, 11:08
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(doom13 @ May 19 2014, 16:27)  Все пять обработчиков и не являются статическими членами класса Timer. У Timer есть только функция регистрации прерывания. Обработчик прерывания необходимо зарегистрировать после создания объекта. Ну да. И в моем ISR() не является членом, но вам это почему-то не понравилось: Цитата В таком исполнении ISR() нельзя сделать членом какого-то класса Цитата(doom13 @ May 19 2014, 16:27)  Тут не понял иронию, что не так в моей реализации? Всё работает и , по-идее, нет никаких противоречий. Можно и унаследовать если есть желание. Никакой иронии. У каждого свои детали реализации.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
May 19 2014, 14:23
|
практикующий тех. волшебник
    
Группа: Участник
Сообщений: 1 190
Регистрация: 9-09-05
Пользователь №: 8 417

|
Цитата(yanvasiij @ May 19 2014, 10:33)  Спасибо за методику... Основной недостаток - продолжительное время разработки. ..."на своей шкуре" испытать плюсы и минусы С++. И плюс, про который все твердят - он помогает использовать старый код вновь гораздо легче, чем просто Си.... объектно ориентированый подход и есть методика. как применять - тут увы и ах кол-во специалистов очень мало. причина - не используют (как правило) опыт ранее накопленный. или по другому - не понимают нафига вообще всё это... лучше всего как применять - описано у Гради Буча. и идут по шагам. 1) анализ 2) дизайн 3) программирование т.е. из вышесказанного можно сразу увидеть - если перескочить через 2 пункта и начать с третьего - то нифига это уже не ОО(а, д, п)... это будет уже написание программы на си плас плас в стиле азм... что собственно встречается так часто, как наверное и упоминание о том, что ОО это фигня... надо понимать, что это инструмент. и если его юзать по неназначению, то и результат будет такой-же... нужно понимать, что печка (при любом раскладе) это ничто иное как бизнес задача(она-же поставленная задача, она же цель всего предприятия касаемое программирования, она же фундамент для дальнейших построений)... т.е. глупо говорить об абстрактном , типа что лучше, наследование или агрегация... это глупость..т.к. автоматически выпадает из ОО, и спор превращается программирование ради программирования. Отсюда и понятно, что написание библиотек впрок - такое-же сомнительное занятие. из той же оперы - юзанье неких шаблонов с заготовками поведения (их можно юзать для обмена информацией, как лексику предметной области конечно же). т.е. первична задача. вторично как и какими средствами. на самом деле пока Вы один на один с задачей - то проблемы собственно и нет. все кто "умеет" - невольно быстро в уме проигрывают первые два пункта. кто-то честно. кто-то пытается натягивать на свои знания технические решения или ещё хуже - подгонять задачу под свои решения(обычно такие люди ноют что дескать это нудная работа, не нужная, много времени занимает, постоянно убеждают заказчика что дескать надо апсолютно по другому думать или делать в жизни, потому как программа не получается...и т.д.). когда собирается команда 2 и более человек - вот тогда все ослинные уши восприятия и вылазят на ружу. ОО это метода. и она вбирает в себя такие плюсы как статический код на всём протяжении разработки, удобство записи исходного кода, масштабируемость, гибкость и т.д..
|
|
|
|
|
May 20 2014, 00:22
|
Местный
  
Группа: Свой
Сообщений: 321
Регистрация: 23-12-11
Из: Уфа
Пользователь №: 69 041

|
megajohn doom13 andrewlekar Сергей Борщ msalov Спасибо! Очень полезные дебаты состоялись, есть о чем подумать. Цитата(kolobok0 @ May 20 2014, 00:33)  объектно ориентированый подход и есть методика. как применять - тут увы и ах кол-во специалистов очень мало. причина - не используют (как правило) опыт ранее накопленный. или по другому - не понимают нафига вообще всё это... Цитата(A. Fig Lee @ May 20 2014, 03:29)  На маленьких задачах преимущества C++ не очевидны. ... Я не спорю, что С++ для маленьких задач это, как использовать трактор для вскапывания земли в горшке с цветком. Просто у меня действительно начали вырисовываться большие задачи, поэтому я начал всерьез задумываться о подходе к программированию. Дело в том, что после десятка проектов и после значительного усложнения реашаемых задач пришел к выводу, что нужно хорошо подумать, хорошо по-проектировать прежде чем хвататься за клавиатуру. Нужно проработать концепцию, нужен этап еще до алгоритмов. Когда мыслишь процедурно, а не объектно, нет инструмента и нет какой то методики позволяющей разбить решаемую задачу на логические куски. Когда программисты пишут на Сях, каждый простите "др...ет как хочет". А когда люди пишут на ООП, они проектируют вполне конкретными методиками, тот же uml или idef. Я не говорю, что это лекарство в моем случае. Я просто хочу проверить поможет ли это мне на этапе проектирования. Конечно та задача, которую я озвучил выше мелковата для ООП, возникают вполне обоснованные вопросы типа "Нафига тут ООП?!". Но я бы замучался расписывать задачу скажем распознавания лиц с видеопотока, а уже если бы мне начали помогать ее разбивать на классы тут...
|
|
|
|
|
May 21 2014, 23:22
|

Профессионал
    
Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045

|
смешали всё. Ну во первых в avr-gcc от winavr нет операторов new и delete. Кто хочет с++ от winavr - должен это учесть. Во 2-ых: C++ != ООП я пишу всё исключительно на с++. где нужно - делаю классы, где нужно наследование, где нужно - динамику и контейнеры. А где не нужно - всё равно на с++, пусть даже и выглядит прога в стиле си. Зачем мне помнить на каком языке написана та или иная программа? Или тот или иной файл? Потом понадобится кусок кода из одного проекта использовать в другом - а они на разных языках. Пиши обёртки.... зачем это нужно? И совет новичкам: хотите си - учите си. Хотите с++ - учите с++. (я бы советовал всёже с++). Не нужно писать на си, если нет ооп, и на с++ если есть ооп. Зачем учить 2 языка? Лучше углубитесь в изучение с++, при этом можно писать и без классов, и без стл, и без динамики, без ооп. По мере развития изучайте/добавляйте всякие няшки, которые отличают с++ от си. Даже без ооп с++ стоить юзать только за bool и ссылки, спэйсы..... Также в с++ удобно, что переменную можно объявить непосредственно перед использованием, в всяких форах. Цитата Я не спорю, что С++ для маленьких задач это, как использовать трактор для вскапывания земли в горшке с цветком. Несогласен полностью. такой код/гаршок Код int main () { printf("Hello world!") for(;;); return 0; } Где тут пахата трактором? компилируй компилятором с++, тот же хекс получится. есть канечно "учителя" по с++ которые дают такие уроки. Цитата и сделаем из нее программу на C++: Код #include <iostream> #include <stdexcept> class App { public: int Run() { std::cout << "Здраствуй Мир!!!\n"; throw std::runtime_error("Что-то плохое в нашей программе случилось."); return 0; } ~App() { std::cout << "До свиданья.\n"; } };
int main(void) { try { App().Run(); } catch(...) { throw; } return 0; } Чистой воды оверинженеринг (да ещё с ошибками). Такой перегруз можно и на си устроить и на асме.
|
|
|
|
|
May 21 2014, 23:52
|

Профессионал
    
Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045

|
Цитата Ссылки полностью перекрываются указателями не перекрываются. указатель может указывать куда угодно, например на 0. безопасный код. Код void f(MyType& i) { i = 100; } тоже безопасный код, но с указателем Код void f(MyType *i) { if(i != 0 ) *i = 100; } Но и это не 100% безопасно.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|