|
|
|||||||||||
Использование указателя на метод вместо виртуального метода20.11.2010, 12:33. Показов 7285. Ответов 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 | |
|
Переопределение виртуального метода переопределение виртуального метода Ошибка создания виртуального метода? Реализовать перегрузку виртуального метода Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
| Опции темы | |
|
|
Новые блоги и статьи
|
|||
|
сукцессия 37. Внедрил дипсик в свой оркестр из ИИ. У него закончилось пространство чата, потому опубликую выводы из его работы здесь
anaschu 21.07.2026
====================================================================
КОНТЕКСТ: Моделирование микоризной сукцессии (AM → ECM)
====================================================================
. . .
|
сукцессия 36. Делаю прогоны модели около порога бифуркации (превращения эндо микоризы в экто микоризу)
anaschu 21.07.2026
СУКЦЕССИЯ МИКОРИЗ: КАК МАТЕМАТИКА ОБЪЯСНЯЕТ ПОДЗЕМНУЮ ВОЙНУ
Мы привыкли думать, что лес — это деревья. А грибы — это то, что мы собираем в корзинку осенью. Но если заглянуть под землю, окажется,. . .
|
ИИ и человечность
kumehtar 21.07.2026
Забавно, что общаясь с ИИ, я замечаю, насколько он высказывается умно, и насколько верит в людей. Он умеет прощать. Он знает как отвечать не обесценивая опыт других людей, даже если сам не верит. Он. . .
|
Нейтральные знания ..., ... чистая наука. Пока что-то проходит модерацию на Хабре, стоит развить мысль ...
Hrethgir 20.07.2026
К таким радикальным взглядам я конечно в той публикации не приходил, но чтобы скоротать вечер, решил углубиться немного.
1. Почему показания термометра заряжены целью?
Цель заложена в самом. . .
|
|
Установка нескольких штампов электронной подписи в строго определенных местах файла docx
ВладимирСамохин 19.07.2026
(В!) Работа с Электронной подписью - это неотъемлемая часть современного документооборота. Но что делать, если нужно поставить несколько штампов электронной подписи в строго определенных местах. . .
|
сукцессия 35. Научная статья о проделанной работе
anaschu 19.07.2026
Написал в формате латекс и пдф
|
Вангую, что это не пройдёт модерацию, и на неделе я запущу свой сервер.
Hrethgir 19.07.2026
Эта публикация сейчас в песочнице и ждёт приглашения.
https:/ / habr. com/ ru/ sandbox/ 295048/
По ссылке 403. Не очень информативно такую ссылку постить.
Запись от Usaga размещена Сегодня в 06:46 . . .
|
сукцессия 33. открытые вопросы от клауде
anaschu 19.07.2026
"Что накопилось за эту часть А — тринадцать правок, из которых шесть пришли из ваших вопросов и каждая оказалась реальной ошибкой, а не калибровкой: односторонний симбиоз, отсутствующий листопад,. . .
|