|
|
|||||||||||
Использование указателя на метод вместо виртуального метода20.11.2010, 12:33. Показов 7235. Ответов 45
Метки нет (Все метки)
Имеется базовый класс Base. Имеется производный от Base класс Derived. В классе Derived требуется выполнить некоторое действие, которое практически полностью эквивалентно для любого производного от Base класса, за исключением небольшого фрагмента.
Схематично код выглядит так:
0
|
|||||||||||
| 20.11.2010, 12:33 | |
|
Ответы с готовыми решениями:
45
Вызов виртуального метода базового класса из указателя производного Почему при переопределении виртуального метода в производном классе выводится метод базового? Использовать метод transform() вместо метода sort() |
|
Делаю внезапно и красиво
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
|
|||||||||||
| 16.04.2011, 14:55 | |||||||||||
|
А так нельзя?
0
|
|||||||||||
|
|
||
| 16.04.2011, 15:30 [ТС] | ||
|
0
|
||
|
Делаю внезапно и красиво
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
|
||
| 16.04.2011, 16:03 | ||
|
Просто, не совсем ясна суть манипуляций, но тебе виднее, конечно, продолжай извращаться.)
0
|
||
|
|
||
| 16.04.2011, 17:14 [ТС] | ||
|
Общая постановка задачи. Есть чёрный ящик, в этот чёрный ящик надо отдать пару "указатель на экземпляр + указатель на метод". Вариант с классами Basi и Dervied я привёл условно, чтобы можно было описать пример того, что именно хочется сделать через указатель на метод. Для моего примера конечно же можно сделать вызов Exec, а потом вызов Tail1. Только это для упрощённой модели можно так просто сделать. Расширенный вариант выглядит так: в метод Exec тащится __closure-указатель (который есть пара "указатель на экземпляр + указатель на метод"). Внутри метода Exec создаётся поток, в потоке запускается программа, написанная на Lua, в неё передаётся моя пара, транзитно пролетает через коды на Lua и "внизу" вызывает код на Си++, который делает вызов через эту пару. Зачем так сложно? Любую сложный интерфейс, который взаимодействует с пользователем, можно написать двумя способами. Первый способ заключается в том, чтобы реализацию интерфейса сделать простой, сам интерфейс не очень удобный для пользователя и переложить все свои проблемы на плечи пользователя. Второй способ заключается в том, что реализацию интерфейса сделать сложной, но при этом получив простой интерфейс, который будет удобным в использовании. Я всегда иду по второму пути (если это возможно) Пример неудобного в использовании интерфейса: борландовский класс TThread. Чтобы им пользоваться. надо определить свой класс, который является производным классом от TThread, переопределить метод Execute, реализовать событие OnTerminate, в своём основном классе обеспечить возможность для доступа ко внутренним данным и методам (потому что часть, исполняемая в потоке, реализована в другом классе). Для маленькой программы конечно же это всё сойдёт, но когда пишешь что-то большое - то разводится очень много мусора вокруг создания потока. Оговорюсь сразу, что это не претензия к борланду: этот класс является лишь некоторым классом низкого уровня, над которым пользователь будет строить обёртку, удобную в конкретной программе. Просто пытался показать пример неудобного интерфейса и как его сделать удобным Удобным в использовании была бы надстройка над таким интерфейсом. К нашему классу (с которым мы работаем и который будет рожать поток) нам нужно добавить в родители некий базовый класс, а в момент рождения потока дёрнуть метод с прототипом типа "StartThread (f1, f2)", где f1 - это указатель на метод, который будет запущен при старте потока, f2 - указатель на метод, который будет запущен в главном процессе после завершения потока. Такой интерфейс очевидным образом использовать намного удобнее
0
|
||
|
Делаю внезапно и красиво
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
|
|||||||||||
| 16.04.2011, 17:23 | |||||||||||
|
Про "извращённость" я сказал из-за того, что ты там выше писал, что тип не известен. В (почти строго) типизированном языке избавляться от типов лично мне кажется извращением.)
Этот код делает то же самое, но без каких либо вопросов:
0
|
|||||||||||
|
|
||||||||
| 16.04.2011, 17:41 [ТС] | ||||||||
0
|
||||||||
|
Делаю внезапно и красиво
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
|
||||||
| 16.04.2011, 18:08 | ||||||
0
|
||||||
|
Делаю внезапно и красиво
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
|
||
| 16.04.2011, 18:20 | ||
|
Тебе же нужно после выполнения blackbox выполнить func?
При этом тип объекта неизвестен (через void*)? Как ты будешь выполнять какую-либо работу в blackbox, если тебе не известен тип объекта? Всё что ты сможешь сделать, это вызвать переданный метод func. Вот потому и непонятно мне ничего.(
0
|
||
|
|
||||
| 16.04.2011, 18:27 [ТС] | ||||
|
0
|
||||
|
Делаю внезапно и красиво
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
|
|||||||
| 16.04.2011, 18:41 | |||||||
|
Добавлено через 2 минуты
0
|
|||||||
|
Делаю внезапно и красиво
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
|
||||||
| 16.04.2011, 19:10 | ||||||
|
В дополнение к коду выше
внутренности BlackBox без шаблонов, дополнительных классов и прочих плясок с бубнами Все пляски вокруг него. И никаких бубнов. Всё логично и просто.
0
|
||||||
|
|
||
| 16.04.2011, 23:00 [ТС] | ||
|
0
|
||
|
В астрале
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
|
|
| 16.04.2011, 23:50 | |
|
Evg, Используя расширения языка для конкретного компилятора писать код - плохая затея. Если тебе нужен только borland то и не парься, используй closure.
0
|
|
|
Делаю внезапно и красиво
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
|
||
| 17.04.2011, 07:32 | ||
|
Библиотека ничего о пользовательских классах знать не будет, она будет знать только об интерфейсе функтора Base и всё. Добавлено через 53 секунды Я не стал писать код инициализации функтора, там просто присваивание адреса...
0
|
||
|
Модератор
8982 / 6749 / 921
Регистрация: 14.02.2011
Сообщений: 23,875
|
|
| 17.04.2011, 08:26 | |
|
Evg,
еще раз повтори(много написано запутался) чем тебя не устраивает Callback? для таких вещей по моему он и создан. что значит неправильный this? Не тот класс? Не тот экземпляр? и чем не устраивают Мессаги?
0
|
|
|
|
||||||||||
| 17.04.2011, 10:13 [ТС] | ||||||||||
|
Давай вернёмся к примеру из последнего абзаца поста #24. Постановка задачи, например, такая. Пользователь пишет класс окна (TForm). Нужно скачать из инета картинку и отобразить её на форме. Если скачивание выполнять в главном процессе, то в момент скачивания приложение будет "висеть": т.е. оно никак не будет реагировать на нажатия кнопок, не будет перерисовываться если поверх него протащить другое окно и т.п. Чтобы этого избежать, надо процесс скачивания утащить в поток. Пока картинка скачивается в потоке, приложение живёт своей жизнью: реагирует на нажатия на кнопочки, менюшки и прочие события. Как только картинка скачалась, то главный процесс каким-то образом об этом узнает и вызовет код, который отрисует картинку на форму (потому что из потока рисовать нельзя). Как такой набор действий сделать максимально удобным для пользователя? У меня работает следующий вариант. Всё то, что начинается с User - это то, что пишет пользователь, а с Lib - это библиотека. Схематично:
Если ты можешь предложить что-то более удобное для пользователя (а не для того, кто будет библиотеку поддержки реализовывать) - предложи Добавлено через 44 секунды И заодно объясни, что такое Callback Добавлено через 10 минут Да, вот ещё. Библиотека поддерживает возможность работы без потока. Т.е. LibStartThread может запустить UserDownloadImage и UserDisplayImage последовательно в главном процессе - сие удобно для процесса отладки, если возникает подозрение, что проблема обусловлена работой с потоком. Переключение между двумя режимами опять-таки делается одним лёгким движением руки
0
|
||||||||||
|
Делаю внезапно и красиво
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
|
|||||||
| 17.04.2011, 10:40 | |||||||
|
Я повторю код.
Если в BlackBox передавать по ссылке, то ещё проще код сделать можно. Добавлено через 2 минуты Шаблоны используются только в пользовательском коде и можно обойтись без них. Это просто облегчение жизни пользователю. BlackBox шаблоны не использует.
0
|
|||||||
|
|
||
| 17.04.2011, 11:11 [ТС] | ||
|
Deviaphan, вот сравни твой код (пост 39) и мой (пост 38). В моём случае дополнительных действий раз-два и обчёлся, а в твоём случае пользователю надо писать кучу дополнительного кода. В твоём коде нет раздельного запуска двух методов по отдельности (т.е. ты в методе Execute запускаешь их одновременно). Чтобы обеспечить раздельный запуск методов, тебе придётся описывать два пользовательских класса Functor. Не говоря уж о том, что пользователь при таком раскладе свои методы ОБЯЗАН называть func1 и func2 (в противном случае работать не будет). Т.е. твой способ подразумевает перекладывание большого количества проблем с автора библиотеки на пользователя библиотеки.
Добавлено через 9 минут
0
|
||
| 17.04.2011, 11:11 | |
|
Переопределение виртуального метода переопределение виртуального метода Ошибка создания виртуального метода? Реализовать перегрузку виртуального метода Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
Сезонность закисления почв
anaschu 04.07.2026
200 часов это все равно моловато. Есть ситуации, но нестандартные, когда смена происходит за 5 лет.
Но обычно это 50 лет и более.
Наверное, закисление почвы происходит сезонно в средней. . .
|
В чем ценность человеческого опыта в глобальном смысле?
kumehtar 03.07.2026
Возможно, ценность человека не в том, что он однажды достигает мудрости, а в том, что он становится носителем карты пути. Он знает не только истину, но и последовательность внутренних изменений,. . .
|
интеграция AnyLogic с самописным REST API и переход на Odoo
anaschu 03.07.2026
Успешная интеграция AnyLogic с самописным REST API и переход на промышленную Odoo WMS
Сегодня проделал огромный путь от простой симуляции физических процессов до построения полноценной. . .
|
Поиск всех путей на ориентированном графе. Linux
dcc0 02.07.2026
Переработка старого кода из моей статьи.
Через несколько переработок от PHP кода к C89 (надеюсь, 89).
Но довольно запутанно получилось. Код для Linux.
Но если убрать time и то, что с ним. . .
|
|
Сам себя обучал rest api
anaschu 02.07.2026
Педагогический лайфхак: Почему чистый REST API для ученика намного круче, чем готовые библиотеки
Когда мы отказались от капризного JAR-файла AnyLogic и переписали код на стандартный HttpClient,. . .
|
rest api anylogic - выполнение модели на своём русском сайте
anaschu 02.07.2026
Как подружиться с AnyLogic Cloud API, победить провайдеров и развернуться Java-бэкенд в Docker на бесплатном хостинге: Двухдневный лог борьбы
Всем привет! Хочу поделиться свежим (и довольно. . .
|
Где деньги лежат
kumehtar 02.07.2026
Это - японская подводная лодка I-52 (тип C2, кодовое имя Momi) вышла из Японии в марте 1944 года с миссией в оккупированную немцами Францию (Лорьян). Это была одна из «Янаги»-миссий по обмену. . .
|
Krabik для WoW 3.3.5a, многоязычный
AmbA 02.07.2026
Допилил бота, думаю что окончательно. Изменения:
- добавлена многоязычность
- добавлено снятие скриншотов
- добавлено поддержание бафов хождения по воде (для жреца, дк и шамана)
- и так, по. . .
|