ReAl 0 7 ноября, 2009 Опубликовано 7 ноября, 2009 · Жалоба А что это? А то может мне тоже это нравится, а я и не знаю ;) ---- Почитал. Пока не понял, нравится ли... Но скорее да, чем нет:) Вчера вопрос видел, но уже выпадал в осадок. Создал новую тему, чтобы тут не мешать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Waso 1 7 ноября, 2009 Опубликовано 7 ноября, 2009 · Жалоба Ну и нормально Только #if defined (PORTA) - лишнее, ибо не будет вызываться, пока вы не определите Pin<'A'...>. В этом прелесть шаблоновДа? А я ведь сначала без этих излишеств написал. У меня WinAVR тогда ругается'PORTE' was not declared in this scope ну и действительно такого порта нет в восьмой меге например. А компилятор всетаки анализирует весь текст видимо. Может я чтото не так сделал? С другой стороны для порта A дейсвительно это лишняя проверка, потомучто этот порт есть у всех авр-ок По поводу режима ноги - для сложных случаев я оставил режим BIDIR. Можно еще режимов напридумывать. Я ж ведь ради чего это делаю - чтобы не париться с инициализацией ножек. Хочется чтоб это все делал конструктор. Вот кстати непонятка: если обьявление Pin<'A'...> сделано НЕ внутри какойто функции, то куда вставит компилятор код конструкторов? А вы, похоже, смотрели вариант для stm32?Да. Но я просмотрел всю тему. Полезного почерпнул не только из последнего поста. :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 18 7 ноября, 2009 Опубликовано 7 ноября, 2009 · Жалоба У меня WinAVR тогда ругается'PORTE' was not declared in this scope Хм. Действительно. Надо подумать:) По поводу режима ноги - для сложных случаев я оставил режим BIDIR. Можно еще режимов напридумывать. Я ж ведь ради чего это делаю - чтобы не париться с инициализацией ножек. Хочется чтоб это все делал конструктор. Зачем плодить сущности? Пусть её инициализирует конструктор, но не конструктор ножки, а конструктор объекта, которому принадлежит ножка. Ну хотя дело конечно ваше:) Вот кстати непонятка: если обьявление Pin<'A'...> сделано НЕ внутри какойто функции, то куда вставит компилятор код конструкторов?В глобальную инициализацию. Обычно после обнуления секции BSS.Но я просмотрел всю тему. Полезного почерпнул не только из последнего поста. :) Это хорошо:) Просто мне показалось, что вариант MSP больше подходит для AVR. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Waso 1 24 ноября, 2009 Опубликовано 24 ноября, 2009 · Жалоба Продолжу задавать вопросы по плюсам в этой теме. Предыстория та-же. Написал класс клавиатуры MtxKeyboard со статическими переменными и функциями. Не забыл добавить в него виртуальные функции, которые будут и у наследников. Наследники такие: template<int row, int col> class MtxButton : public MtxKeyboard { public: /*virtual /*inline*/ uint8_t Get() { return State[(col-1)]&(1<<(row-1));} /*virtual /*inline */ uint8_t Pressed() { return (Get()&&(Ticks>=KEYPRES_TRESHOLD))? 1 : 0;} /*virtual /*inline */ uint8_t Locked() { return (Get()&&(Ticks>=KEYLOCK_TRESHOLD))? 1 : 0;} }; Простенькая тестовая прога: MtxButton<1,1> Key_Num1; MtxButton<1,2> Key_Num2; MtxButton<1,3> Key_Num3; MtxButton<1,4> Key_Num4; //========== еще 16 кнопок class Client_c {public: Client_c(MtxKeyboard * pB):pButton(pB){}; MtxKeyboard * pButton;}; Client_c Client_1(&Key_Num1); Client_c Client_2(&Key_Num2); Client_c * pClient[]={&Client_1,&Client_2}; int main(void){ for(;;) { Keys.Scan(); if (Key_Num1.Pressed())pin1.Toggle(); if (Client_1.pButton->Pressed())pin2.Toggle(); } return 0;} на максимальной оптимизации в WinAVR130309 компилится в 500+ байт кода и около 10байт ОЗУ. Но вот как только я делаю функции наследников виртуальными - таже прога компилится в 3000+ байт кода и 230байт ОЗУ. Я в курсе про таблицу вызова виртуальных процедур, но 2 тыщи слов она не сожрет. В чем проблема? По сгенеренному асму не могу понять.. Какбудто оптимизация отключается. На всякий случай приложил исходники. virtual.zip Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
xvr 12 24 ноября, 2009 Опубликовано 24 ноября, 2009 · Жалоба Как только функции стали виртуальными у класса MtxButton<> появились собственные данные - указатель на таблицу виртуальных методов. Соответственно появились конструкторы, что бы эти данные проинициализировать. Далее, т.к. объекты статические и с конструктором, появились вызовы конструкторов до main, что потянуло всю run-time поддержку для вызова таких конструкторов и деструкторов. Можно спросить - нафига наследовать MtxButton от MtxKeyboard , которая по жизни должна быть одна на всех, да еще и с виртуальными функциями, что вообще нонсенс. Такое наследование логически породит столько клавиатур, сколько будет создано кнопок. Если уж хочется приткнуть куда нибудь клавиатуру, сделай так: class BtnBase { protected: static MtxKeyboard keyboard; }; template<int row, int col> class MtxButton : public BtnBase { public: uint8_t Get() { return keyboard.State[(col-1)]&(1<<(row-1));} uint8_t Pressed() { return (Get()&&(keyboard.Ticks>=KEYPRES_TRESHOLD))? 1 : 0;} uint8_t Locked() { return (kGet()&&(keyboard.Ticks>=KEYLOCK_TRESHOLD))? 1 : 0;} }; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Waso 1 25 ноября, 2009 Опубликовано 25 ноября, 2009 · Жалоба Можно спросить - нафига наследовать MtxButton от MtxKeyboard , которая по жизни должна быть одна на всех, да еще и с виртуальными функциями, что вообще нонсенс.Ну я сделал все члены класса MtxKeyboard статическими, так что этот класс не должен размножаться при появлении дочерних классов. Но ваша запись со вложенным статическим классом более грамотна, спасибо. Виртуализовать функции кнопок я хочу чтобы была возможность загонять указатели на них в массивы и потом динамически перебирать в цикле. Хотя это и не всегда надо и всегда можно обойти, но если есть возможность без огромных неоправданных затрат использовать красивости плюсов - я хочу их использовать. Просто я только начинаю осваивать плюсы и могу легко сваять слона из мухи по неопытности. Такчто не раздражайтесь пожалуйста сильно по этому поводу. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Waso 1 26 ноября, 2009 Опубликовано 26 ноября, 2009 · Жалоба Ладно, чтобы не смотрели на меня косо, открою карты. =) Мне надо написать прогу для работы пульта оператора, к которому подключается до 20 панелей клиентов. Для каждого клиента на пульте есть кнопка и двухцветный светик. Поведение всех клиентов описывается одной машиной состояний (StateMachine). Я задумал описать класс клиента, который содержит статус, процедуру обработки состояний, и ссылки на свои кнопку и светик, которые инициализируются в конструкторе. Кнопки и светики описаны в отдельных классах с интерфейсом "Нажата?", "Включить красный", "Выключить" и тп.. В main будет цикл, который будет перебирать массив указателей на классы клиентов и запускать процедуру обработки очередного клиента. Одна виртуальная функция добавляет 50байт кода для каждой кнопки или светика. Умножаем на кол-во кнопок и светиков, и еще на колво виртуальных методов и получаем много килобайт, невлезаем. Вот я и думаю как бы поизящнее решить эту проблему, чтобы поменьше писанины и пооптимальнее код. От виртуальных функций можно избавиться, избавившись от шаблонов и заплатив парой байт ОЗУ на каждую кнопку и светик - помнить номер строки и столбца не как параметр шаблона, а как константу. Интересно как решали такую проблему другие. =) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
xvr 12 26 ноября, 2009 Опубликовано 26 ноября, 2009 · Жалоба Одна виртуальная функция добавляет 50байт кода для каждой кнопки или светика.Это не виртуальная функция добавляет, а шаблонный класс. Для такого применения шаблоны не годятся. Вот я и думаю как бы поизящнее решить эту проблему, чтобы поменьше писанины и пооптимальнее код. От виртуальных функций можно избавиться, избавившись от шаблонов и заплатив парой байт ОЗУ на каждую кнопку и светик - помнить номер строки и столбца не как параметр шаблона, а как константу. Именно так. Пара констант (не обязательно в ОЗУ, кстати) займут много меньше кода, чем 3 функции. Интересно как решали такую проблему другие. =)Можно вообще отказаться от констант, если передавать их в качестве параметра (или глобала) в цикле в main. Такое решение позволит съэкономить память, но идет вразрез с ООП. (Собственно при таком подходе это будет обычная, не ООП программа) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться