![]() |
Здравствуйте, гость ( Вход | Регистрация )
![]() ![]() |
![]() |
lanz |
![]()
Сообщение
#1
|
![]() Старейший участник ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 690 Регистрация: 28.12.2012 Пользователь №: 3660 Спасибо сказали: 113 раз(а) Репутация: ![]() ![]() ![]() |
В общем суть такова, есть некоторое количество(N) классов, наследующих от общего предка.
У предка есть интерфейс управления для обработки команд. Раскрывающийся текст
Естественно конкретные реализации по разному обрабатывают команды. В первом приближении примерно так: Раскрывающийся текст
Естественно это не очень красиво, поэтому сразу второе приближение: Раскрывающийся текст
В map хранятся указатели на функции члены. Естественно мне захотелось вынести все это в базовый класс. Раскрывающийся текст
Загвоздка в том что мы не можем добавлять функции-члены наследующих классов в список. Можно конечно обойтись списком свободных функций, но интересно, как описать Map который будет содержать функции члены не только базового но и производных классов? |
|
|
Влад |
![]()
Сообщение
#2
|
Участник ![]() ![]() Группа: Участник Сообщений: 146 Регистрация: 20.3.2009 Из: Санкт-Петербург Пользователь №: 627 Спасибо сказали: 46 раз(а) Репутация: ![]() ![]() ![]() |
Вот так и описать. А заполнение этого мэпа происходит либо в конструкторе соответствующего объекта (в принципе, базовый класс может добавлять только свои функции-члены, дальше производные добавляют свои), либо вообще этот мэп будет статический константный член на каждый класс - и тогда заполнение можно сделать в компайл-тайме.
А еще я бы предложил подумать вот над чем: по-моему, тут как раз на схему обработки очень хорошо ляжет паттерн "Посетитель" (Visitor). |
|
|
lanz |
![]()
Сообщение
#3
|
![]() Старейший участник ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 690 Регистрация: 28.12.2012 Пользователь №: 3660 Спасибо сказали: 113 раз(а) Репутация: ![]() ![]() ![]() |
Цитата Вот так и описать. Не выходит. Цитата error C2647: '.*' : cannot dereference a 'void (__thiscall DerivedN::* )(QVariant)' on a 'Base' error C2440: 'newline' : cannot convert from 'Base *' to 'DerivedN *' Так понимаю поскольку это downcast, он отказывается неявно его преобразовывать, и в принципе правильно. Цитата А еще я бы предложил подумать вот над чем: по-моему, тут как раз на схему обработки очень хорошо ляжет паттерн "Посетитель" (Visitor). Посетитель не очень подходит ИМХО, поскольку у каждого наследника есть 3-15 уникальных для него команд. Или я неправильно понимаю Посетителя или он нужен когда одну и ту же команду можно применить к объектам разного типа. |
|
|
Влад |
![]()
Сообщение
#4
|
Участник ![]() ![]() Группа: Участник Сообщений: 146 Регистрация: 20.3.2009 Из: Санкт-Петербург Пользователь №: 627 Спасибо сказали: 46 раз(а) Репутация: ![]() ![]() ![]() |
Так понимаю поскольку это downcast, он отказывается неявно его преобразовывать, и в принципе правильно. И это правильно. Но в наследнике-то ты уже точно знаешь, с объектом какого именно класса ты работаешь; поэтому что мешает downcast'ить "ручками"? Или я чего-то не понимаю? Если так, попробуй накидать код минимального примера, иллюстрирующего проблему, - попробуем разобраться "на кошках". |
|
|
lanz |
![]()
Сообщение
#5
|
![]() Старейший участник ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 690 Регистрация: 28.12.2012 Пользователь №: 3660 Спасибо сказали: 113 раз(а) Репутация: ![]() ![]() ![]() |
Downcast-ить то его можно, только проблема в том что функции-члены от производного класса не влезают в список функций членов базового.
Приложил минимальный пример.
Прикрепленные файлы
|
|
|
lanz |
![]()
Сообщение
#6
|
![]() Старейший участник ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 690 Регистрация: 28.12.2012 Пользователь №: 3660 Спасибо сказали: 113 раз(а) Репутация: ![]() ![]() ![]() |
Сделал так:
Раскрывающийся текст
Раскрывающийся текст
Раскрывающийся текст
Пинки, мысли вслух, философские размышления и критика приветствуются! ![]() |
|
|
Алексей1153 |
![]()
Сообщение
#7
|
![]() фрилансер ![]() ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 2943 Регистрация: 19.6.2010 Из: Обливион Пользователь №: 1822 Спасибо сказали: 215 раз(а) Репутация: ![]() ![]() ![]() |
lanz, все названия функций - в текстовом виде, все параметры- в текстовом виде. Работать будет как часы (небольшая потеря производительности, причём вряд ли заметная - плата за универсальность)
по сути - экземпляру передаётся XML с названием функции и перечисленными атрибутами - параметрами (с их значениями) Сообщение отредактировал Алексей1153 - 26.3.2013, 18:06 |
|
|
Iron Bug |
![]()
Сообщение
#8
|
![]() Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Модератор Сообщений: 1611 Регистрация: 6.2.2009 Из: Yekaterinburg Пользователь №: 533 Спасибо сказали: 219 раз(а) Репутация: ![]() ![]() ![]() |
Вот, по-быстрому написала, как в С++11 это сделать можно.
Это без Qt(я её не юзаю), но не суть. Можно любые классы и контейнеры использовать, это не принципиально. У меня заюзан простой map и функция, принимающая int, для примера. В GCC компилируется с опцией -std=c++11. Раскрывающийся текст
Сообщение отредактировал Iron Bug - 26.3.2013, 22:45 |
|
|
lanz |
![]()
Сообщение
#9
|
![]() Старейший участник ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 690 Регистрация: 28.12.2012 Пользователь №: 3660 Спасибо сказали: 113 раз(а) Репутация: ![]() ![]() ![]() |
Цитата Вот, по-быстрому написала Настоящая черная магия ![]() Супер, спасибо! Насколько я понимаю, в старом std/tr1 так не получится или я что-то упустил? Цитата lanz, все названия функций - в текстовом виде, все параметры- в текстовом виде. Кстати насчет массивов данных, что тут лучше, base64? Нормально будет для объемов до 500Кб? А то что то меня душит, непойму что ![]() |
|
|
Iron Bug |
![]()
Сообщение
#10
|
![]() Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Модератор Сообщений: 1611 Регистрация: 6.2.2009 Из: Yekaterinburg Пользователь №: 533 Спасибо сказали: 219 раз(а) Репутация: ![]() ![]() ![]() |
Насколько я понимаю, в старом std/tr1 так не получится или я что-то упустил? наверное, можно, если буст прикрутить. там тоже есть какие-то ограничения на компилятор, но не такие строгие. в бусте связывание уже давно было, я даже не помню, с какой версии оно начало поддерживаться. то, что проходит обкатку в бусте, чаще всего потом переходит в стандарт. тут главная проблема - это разные представления "указателей" на методы классов. на самом деле, это нифига не указатели, а сложные структуры, которые не стандартизованы и у каждого компилятора они свои и даже меняются от версии к версии внутри одного компилятора. поэтому делегирование методов комитет по стандартизации переложил на разработчиков стандартных библиотек, идущих вместе с компилятором, что вполне логично. чистого делегирования в С++ нет, зато есть связывание, которое заменяет делегирование на практике. |
|
|
Алексей1153 |
![]()
Сообщение
#11
|
![]() фрилансер ![]() ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 2943 Регистрация: 19.6.2010 Из: Обливион Пользователь №: 1822 Спасибо сказали: 215 раз(а) Репутация: ![]() ![]() ![]() |
стати насчет массивов данных, что тут лучше, base64? Нормально будет для объемов до 500Кб? А то что то меня душит, непойму что жабу не слушай, делай строку хексов 00112233AAFF , а то на конвертации потратишь больше ресурсов ) 500 кб - фигня для нечастых обменов если же всё столь специфично, что нужно часто передавать массивы, то делай для этого отдельный быстрый метод без текста. |
|
|
lanz |
![]()
Сообщение
#12
|
![]() Старейший участник ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 690 Регистрация: 28.12.2012 Пользователь №: 3660 Спасибо сказали: 113 раз(а) Репутация: ![]() ![]() ![]() |
Цитата делай для этого отдельный быстрый метод без текста. В итоге на этом и остановился. Хочется чтобы потом легко распилилась программа на клиент-сервер. Кстати какие лучше протоколы городить чтобы потом на TCP хорошо легло? Свой придумывать с текстовыми командами + сегментами данных или ориентироваться на COM/Dbus, protobuf например? Стоит ли морочится с TCP или сразу лучше взять zmq? |
|
|
Алексей1153 |
![]()
Сообщение
#13
|
![]() фрилансер ![]() ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 2943 Регистрация: 19.6.2010 Из: Обливион Пользователь №: 1822 Спасибо сказали: 215 раз(а) Репутация: ![]() ![]() ![]() |
lanz, а где, что и в каких объёмах будет гоняться ? От этого зависит
если это НЕ локалка, то можно составлять XML или JSON (он полегковеснее), ужимать стандартным
(для ужимаемых случаев, так как короткую строку нет смысла жать) и пересылать. Городить двоичные протоколы - фу фу, пройденный этап ) Потом в определённый момент заколебает несовместимость если это всё локально, то и без сжатия будет летать. Ну там тесты и покажут |
|
|
lanz |
![]()
Сообщение
#14
|
![]() Старейший участник ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 690 Регистрация: 28.12.2012 Пользователь №: 3660 Спасибо сказали: 113 раз(а) Репутация: ![]() ![]() ![]() |
Графики кривых, 5-10К точек, хотелось бы хотябы 10-15 в секунду, локально естественно. Не локально я думаю раз-два в секунду где-то.
XML/JSON/сжатие-растяжение кажется тяжеловато будет. Я тут глядел на камеры которые через Ethernet работают. Там все здорово аж до 30 fps, но они свои драйвера рекомендуют ставить и выделенную сетевуху, так что мне кажется становится тесновато для просто лобового подхода. Надо пробовать в общем ![]() Городить последнее дело, понятно, вот если взять готовый... Как кстати насчет Dbus/COM, ни у кого не было опыта использования? |
|
|
Алексей1153 |
![]()
Сообщение
#15
|
![]() фрилансер ![]() ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 2943 Регистрация: 19.6.2010 Из: Обливион Пользователь №: 1822 Спасибо сказали: 215 раз(а) Репутация: ![]() ![]() ![]() |
|
|
|
Iron Bug |
![]()
Сообщение
#16
|
![]() Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Модератор Сообщений: 1611 Регистрация: 6.2.2009 Из: Yekaterinburg Пользователь №: 533 Спасибо сказали: 219 раз(а) Репутация: ![]() ![]() ![]() |
Как кстати насчет Dbus/COM, ни у кого не было опыта использования? c COM одно время дело имела - это было наследние тех, кто писал проект до меня. не понравилось просто ужасно. может, на С# или каком-нить вижуал бейсике это выглядит проще, но на С++ под него писать очень сложно, особенно если ты не потребитель ресурсов, а сам что-то предоставляешь. потом, регистрация объекта - дело довольно геморное. юзать COM можно, но удовольствия это не доставляет. мне вообще кажется, что последние годы мелкософт хочет отойти от COM и "неуправляемых" (native) приложений. я даже подозреваю их в том, что они из-за этого не хотят развивать и поддерживать компилятор С++. может, это паранойя, но как-то так это выглядит. Сообщение отредактировал Iron Bug - 27.3.2013, 19:38 |
|
|
![]() ![]() ![]() |
![]() |
|
Текстовая версия | Сейчас: 8.6.2025, 6:40 |