Forger 26 12 сентября, 2023 Опубликовано 12 сентября, 2023 · Жалоба 1 minute ago, EdgeAligned said: Такую фиготеку и на процедурном Си принято мутить... там сделать значительно сложнее, скорее получатся костыли, для доступа к которым нужна еще и инвалидная коляска Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
EdgeAligned 86 12 сентября, 2023 Опубликовано 12 сентября, 2023 · Жалоба Не, ничуть не сложнее. Если касаться только пресловутой "изоляции", то всё ровно тоже самое. В С++ появляется только один промежуточный уровень - protected. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 26 12 сентября, 2023 Опубликовано 12 сентября, 2023 · Жалоба 12 minutes ago, EdgeAligned said: Не, ничуть не сложнее. Если не секрет, то какой смысл писать на С как на плюсах? По-моему проще сразу перейти на плюсы и писать в них по началу как в си, "потихоньку" входя в тему плюсов, если вхождение такое уж болезненное )) Так многие делают. Я тоже так делал, оказалось это не больно )) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
EdgeAligned 86 12 сентября, 2023 Опубликовано 12 сентября, 2023 · Жалоба Вышесказанное мной относилось к тому, что собравшиеся здесь понимают ООП лишь как средство "изолировать максимально". Я и ответил, что то же самое без проблем делается на простом Си. И никаких костылей! Ровно то же самое. Иль вы эту возможность просто не использовали чтоль? И еще. "Максимально изолировать" - не самая главная цель. Подчас "максимально изолировать" - означает накостылять лишнего хлама. В погоне за "изоляцией" можно забыть о разумной достаточности. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 26 12 сентября, 2023 Опубликовано 12 сентября, 2023 · Жалоба 5 minutes ago, EdgeAligned said: В погоне за "изоляцией" можно забыть о разумной достаточности. Вот вот! Поэтому попытки в си делать плюсовые фишки для меня кажется как минимум странной затеей. Максимум что пользы от С - это просто набор функций для какой либо насыщенной функциями библиотеки. Где плюсы просто не нужны. Но даже в этом случае используется зачастую уже чужая готовая библиотека, которая правится если очень нужно под себя. Я например просто делаю плюсовые обертки вокруг некоторых сторонних с-библиотек, не трогая оригинальные с-файлы, чтобы в случае их обновления не трогать свой код. Разумеется, это требует времени. В простейшем случае просто создаю namespace c кучей функций вокруг сторонней с-либы. А порой даже вложенные namespace, которые после перерождаются в полноценные классы и т.п Это в двух словах, как например я изолируюсь от стороннего с-кода, которых сходу просто так не убрать из проекта. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
EdgeAligned 86 12 сентября, 2023 Опубликовано 12 сентября, 2023 · Жалоба FreeRTOS написана на простом Си без ООП, и это ничуть не мешает. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
std 8 12 сентября, 2023 Опубликовано 12 сентября, 2023 · Жалоба 7 hours ago, Arlleex said: Вот пример: мне нужно принять строку по UART и выдать ее на дисплей, подключенный по SPI к тому же микроконтроллеру. Хорошо, у меня будет класс работы с UART, унаследованный (каким-то образом) от базового класса последовательного порта (класса-интерфейса). Интерфейс будет иметь виртуальный метод ReadString(), который вернет принятую строку. Разумеется, класс-наследник в рамках реализации конкретного драйвера работы с UART, переопределяет ReadString(), а также расширяет свой функционал (локально), чтобы банально, например, взаимодействовать с прерываниями UART-модуля, или тем же DMA. Соответственно, прикладной код будет работать не с классом этой конкретной реализации порта, а через указатель на тип класса-родителя (интерфейс). И это объектно-ориентированный подход. Тут сразу возникает вопрос: что (какая логика в ООП-парадигме) мешает напрямую использовать объект наследника? Ничто не мешает. Никаких базовых классов вы не обязаны создавать. Наследование не обязательно. Классы не обязательны. В ООП парадигме можно писать на ассемблере или Си. Поёрничаю: почему бы CComPort-у не содержаться в вашем классе качестве композита, в виде агрегата, быть миксином или вообще никак не содержаться, вызывая его функции или например не вызывая функции, а подписаться на него, получая сообщения или периодически проверяя сообщения где-нибудь в общей очереди? Вообще, не кажется ли что совсем наоборот, это CComPort зависит от CUart? 🙂 Читая "будет класс", "класс-наследник", "переопределяет", становится понятно что у вас сложился образ "ООП" обязательно подразумевает наследование. Это не так. Я предлагаю вам начать с людей которые это создали и изучить что же они имели в виду, их цели и как они их добивались. Если открыть страницу OOP и почитать, то становится понятно, что OOP оформился в языке SIMULA и это произошло задолго до C++ и даже до C (1957-1962). Еще полезно изучить что есть SIMULA и для чего создавалось (там немного лукваят хотя бы потому что спонсировали эти исследования и вообще проект компьютера министерство обороны). Вот документ Some features of the SIMULA 67 language. в нем я бы обратил внимание на: Quote The central concept in SIMULA 67 is the "object". An object is a self-contained program, (block instance), having its own local data and actions defined by a "class declaration". The class declaration defines a program (data and action) pattern, and objects conforming to that pattern are said to "belong to the same class". Ибо это и есть самая суть. Все остальное уже рюшечки. Some features of the SIMULA 67 Languge (1968_0007).pdf Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
EdgeAligned 86 12 сентября, 2023 Опубликовано 12 сентября, 2023 · Жалоба Ух ты, теперь оказывается ООП можно даже и на ассемблере? Вау, как круто. Чем дальше в лес, тем толще партизаны 🙂 Интересно, как вы будете писать на ассемблере "полиморфизьмъ и наследование" 🙂 ..."Смешались люди, кони..." Говорите, что "остальное - рюшечки", так? Но ведь "изолировать" можно на обычном базовом бесклассовом Си. Следовательно, Си - объектно-ориентированный язык? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 26 12 сентября, 2023 Опубликовано 12 сентября, 2023 · Жалоба 49 minutes ago, EdgeAligned said: FreeRTOS так любая RTOS - это просто набор с-функций (сервисов), ООП тут если и нужна, то больше для более грамотной организации кода и сокрытия ОС-"требухи" от юзер кода. У меня например есть плюсовые обертки вокруг сторонних ОС, такая схема позволяет не трогать свой код или переносить его с одного камня на другой с разными ОС, т.е. нет жесткой привязки к сторонней библиотеке что-то подобное делает cmsis-os, ведь по сути это некая с-обертка вокруг сторонних RTOS, что тоже вполне логичное решения для некой "стандартизации" кода. Вот например кусок объявления из одного из моих проектов (объявление класса модуля для работы с параметрами и настройкам приложений), еще сырой, но тем не менее: Spoiler #include <AbstractApplication.hpp> #include <Delegate.hpp> //////////////////////////////////////////////////////////////////////////////////////////////////////////////// class Settings : public Module { public: Settings() { name = const_cast<char*>("Settings"); } static struct Signal { Delegate<float()> getUsbVoltage; } signal; static struct Slot { Delegate<int (const char * query, int defaultValue)> getInt; Delegate<bool (const char * query, bool defaultValue)> getBool; Delegate<char * (const char * query, const char * defaultValue, char * resultValue)> getString; Delegate<bool ()> isDiskBusy; Delegate<bool ()> isDiskValid; Delegate<bool ()> isSettingsValid; ...... } slot; static Settings & getInstance(); }; ................ class SettingsLib : public Settings { virtual void connectSignals() final; virtual void connectSlots() final; virtual void run() final; //////////////////////////////////////////////////////////////////////////////////////////////////////////// class TimerUSB : public OS::Timer<kStackSize> { private: virtual void initialize() final; virtual void body() final; public: TimerUSB() : OS::Timer<kStackSize>("Settings.Thread") {} int getInt(const char * query, int defaultValue); char * getString(const char * query, const char * defaultValue, char * resultValue); bool getBool(const char * query, bool defaultValue); bool isDiskBusy() { return(isHostConnected); } bool isDiskValid() { return(diskStatus == 0); } bool isSettingsValid() { return(settingsSize != 0); } ... Delegate<float()> getUsbVoltage; struct Signal { Delegate<float()> getUsbVoltage; } signal; private: OS::Mutex mutex; Hardware::Interrupt usbInterrupt; Hardware::DigitalOutputPin<PA9> pinEnableUSB; void loadAndValidateSettings(); int settingsSize = 0; char * settingsBuffer; bool isHostConnected = true; int32_t diskStatus = 1; bool isTest = false; bool isDebug = false; bool isDemo = false; } timerUSB; ................ }; В коде вообще нет ни намека на конкретную RTOS, да и это не должно иметь для кода никакого значения. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
tonyk_av 44 12 сентября, 2023 Опубликовано 12 сентября, 2023 · Жалоба 3 hours ago, Arlleex said: по своим ощущениям кажется, что самой главной характеристикой ООП является именно полиморфизм. Пожалуй, да, но без наследования это не имеет смысла, поэтому наследование и полиморфизм. И с ролью инкапсуляция соглашусь. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
amaora 24 12 сентября, 2023 Опубликовано 12 сентября, 2023 · Жалоба Исходная цель это построить удобные абстракции, чтобы писанины было меньше, код понятнее, переносимее и другие желаемые свойства на выбор. А что именно называется ОП а, что нет, не так уж и важно. Есть работа с абстрактными объектами через обозначенный интерфейс, значит ОП. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
tonyk_av 44 12 сентября, 2023 Опубликовано 12 сентября, 2023 · Жалоба 1 hour ago, EdgeAligned said: собравшиеся здесь понимают ООП лишь как средство "изолировать максимально" Ничего подобного. Выстраивание иерархии классов позволяет выделить общие части, вынося специфику в наследников. Это в итоге уменьшает размер кода и ускоряет разработку. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 26 12 сентября, 2023 Опубликовано 12 сентября, 2023 · Жалоба 1 hour ago, tonyk_av said: Это в итоге уменьшает размер кода и ускоряет разработку. Неоднократно лично в этом убеждался в своих же собственных старых проектах, перенесенных на новый так сказать плюсовой "движок" ) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
std 8 13 сентября, 2023 Опубликовано 13 сентября, 2023 · Жалоба 19 hours ago, std said: Да, спасибо. Я конечно же имел в виду не было отмены важных концепций. Я бы отметил auto_ptr, который удален в C++17. Но это не значит что удалили концепцию смартпоинтеров. Таки я не прав. В 23 удалили сбор мусора =))) А это всё же концепция. По факту его никто не поддерживал (т.е. его и не было). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 183 15 сентября, 2023 Опубликовано 15 сентября, 2023 · Жалоба В 12.09.2023 в 20:40, Forger сказал: Неоднократно лично в этом убеждался в своих же собственных старых проектах, перенесенных на новый так сказать плюсовой "движок" ) У меня вопрос такого характера. Вот Вы, как я уже понял, за годы программирования на плюсах под МК, выработали некие подходы к архитектуре программ. Я не об именовании переменных и классов. Я о неких неявных соглашениях о взаимодействиях различных частей программы между собой. Во взрослых программах это называют архитектурными паттернами. Например, Вы хорошо разбираетесь в своих исходниках. Я хорошо разбираюсь в своих. Кто-то еще - в своих. Вы используете какие-то архитектурные паттерны проектирования? Я делаю пока что поспешные выводы, что без архитектурных паттернов проектирования, узнаваемого другими программистами (хотя бы как минимум на уровне команды), любой код будет считаться запутанным, не понятным, велосипедным. Вы как раз говорите, что у вас выработался некий подход, который выразился в создании некоего "плюсового движка". Это трактовать как "у меня есть своя коллекция велосипедов" или под этим что-то иное подразумевается? Далее (вопрос уже не конкретно к @Forger). Возможен ли какой-то контроль-указание к жесткой девиртуализации (а если это не возможно - ошибка компиляции) виртуальных вызовов через интерфейсы? ИМХО, в программах под МК компилятор при доступе к объекту по указателю на интерфейс практически всегда может "прощупать" точный тип объекта и заменить виртуальный вызов обычным, выкидывая таблицу виртуальных функций и, соответственно, накладные расходы на вызов. Или это такая же добровольно-принудительная, зависимая от погоды на Марсе, ситуация, как с ключевым словом inline в Си? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться