|
|
|||||||||||
Использование указателя на метод вместо виртуального метода20.11.2010, 12:33. Показов 6978. Ответов 45
Метки нет (Все метки)
Имеется базовый класс Base. Имеется производный от Base класс Derived. В классе Derived требуется выполнить некоторое действие, которое практически полностью эквивалентно для любого производного от Base класса, за исключением небольшого фрагмента.
Схематично код выглядит так:
0
|
|||||||||||
| 20.11.2010, 12:33 | |
|
Ответы с готовыми решениями:
45
Вызов виртуального метода базового класса из указателя производного Почему при переопределении виртуального метода в производном классе выводится метод базового? Использовать метод transform() вместо метода sort() |
|
270 / 176 / 46
Регистрация: 12.03.2010
Сообщений: 494
|
||||||
| 20.11.2010, 20:23 | ||||||
|
Вообще решение через указатели на функции-члены выглядит устрашающе немного. А как это все будет работать зависит уже от компилятора. Можно уточнить задачу, зачем это понадобилось и почему, например, не устраивает чисто виртуальная функция с дефолтным поведением?
Да и само построение логики выглядит немного странно
0
|
||||||
|
|
||
| 21.11.2010, 00:02 [ТС] | ||
|
0
|
||
|
270 / 176 / 46
Регистрация: 12.03.2010
Сообщений: 494
|
|
| 21.11.2010, 00:59 | |
|
Наследование тут, по моему, не лучшее решение. Я буквально месяц назад писал подобную штуку, шаблоны для такого дела - самое оно. Взять тот же function или async для примера. Если нужно выполнить несколько действий, то элементарно организовывается очередь указателей на функции для выполнения, синхронизацию тоже можно запихнуть в исполняющий поток.
1
|
|
|
274 / 175 / 12
Регистрация: 14.03.2010
Сообщений: 501
|
|
| 21.11.2010, 01:00 | |
|
Может, я не до конца понимаю задачу, но почему бы просто не вынести исполнение функции "Tail" из функции "Exec" базового класса в "MyExec" наследованного?
1
|
|
|
84 / 57 / 8
Регистрация: 07.08.2010
Сообщений: 185
|
||||||
| 21.11.2010, 09:23 | ||||||
|
Как вариант можешь передавать в Exec функтор:
1
|
||||||
|
|
||||
| 21.11.2010, 10:15 [ТС] | ||||
|
0
|
||||
|
270 / 176 / 46
Регистрация: 12.03.2010
Сообщений: 494
|
|
| 21.11.2010, 10:41 | |
|
Судя по той теме, тут можно обойтись и чистым С, винда же предоставляет стандартный пул потоков, в который можно просто пихать свои функции для исполнения (я его частенько использовал при написании небольших серверов). А для уведомление потока-обработчика можно использовать те же простенькие ивенты
0
|
|
|
|
||
| 21.11.2010, 10:47 [ТС] | ||
|
0
|
||
|
270 / 176 / 46
Регистрация: 12.03.2010
Сообщений: 494
|
|
| 21.11.2010, 11:29 | |
|
QueueUserWorkItem - самый простой вариант( винда сама все запустит
). Ну, а в стиле С++, мне все же видится асинхронный делегат. Как окончательно проснусь - набросаю простой вариант
0
|
|
|
|
|||||||
| 21.11.2010, 13:41 [ТС] | |||||||
|
Схематично примерно всё выглядит так. Здесь отображаю только код для окна с картинкой (производный класс), потому как базовый класс условно считаем чёрным ящиком, который надо реализовать. Сейчас чёрный ящик реализован через виртуальные методы
Нынешний вариант тоже работоспособен, потому как если нужно исполнять различные действия, то по дополнительному параметру можно настраивать действия внутри Execute1, ... Т.е. вопрос упирается в удобство. Вторым бонусом работы с указателями будет то, что проще организовывать работу с несколькими потоками
0
|
|||||||
|
270 / 176 / 46
Регистрация: 12.03.2010
Сообщений: 494
|
||||||
| 21.11.2010, 15:59 | ||||||
|
Вот самый простенький вариант реализации:
Добавлено через 12 минут В запуске потока код поправиль забыл
0
|
||||||
|
|
|
| 21.11.2010, 16:20 [ТС] | |
|
В твоём коде нет самого главного - вызов события, когда поток завершил работу. В ссылке из 7-го поста я именно для того и поднял тему. По завершении работы потока мне нужно внутри класса окна обработать событие завершения. Неважно каким способом, важно лишь, чтобы это исполнялось в главном процессе. Это гарантирует мне то, что в этот момент мне не придёт никакое другое событие, а потому и не потребуется медитировать с синхронизацией
Добавлено через 13 минут Собственно, callback по завершении работы потока - это единственное, с чем я не могу нормально разобраться (а точнее, я понял, как это делать в контексте окна, но не понял, как это делать "в воздухе"). Так же хочется, чтобы callback'ом был метод класса, а не просто функция. Использование функции для callback'а действий в потоке - это механизм, на котором опирается низкоуровневое (на уровне ОС) создание потоков. И этот механизм хорошо отображается на язык Си, потому как в Си функция она и в африке функция. Чего не скажешь о Си++, ибо метод - он требует косвенного наличия this'а, который в общем случае невозможно в этот механизм включить, потому что при преобразовании this'а к void* (или любому типу, отрезанному от класса) теряется возможность вызвать метод класса. В то время как на Си любые данные можно транзитно передавать через ОС в виде void*. То, чего я хочу - это реализовать УДОБНУЮ В ИСПОЛЬЗОВАНИИ обёртку для классов. И даже что-то более узкое и конкретное: обёртку для работа в классе TForm. Конечно, в качестве callback'а можно использовать и статический метод, но такой способ влечёт за собой дополнительные телодвижения, которые в каждом конкретном случае выливаются в постоянный копипаст. Я в очередной раз специально в первом посте ставил вопрос максимально абстрактно, потому что давно знаю, что при конкретной постановке сложного вопроса в 9 случаях из 10 я услышу ответ не на свой вопрос, а на то, что мне в данный момент не интересно. Точно так же пост #12 является ответом на вопрос, который я не задавал. Хотя, несомненно, этот код является полезным материалом. Но не в контексте данного вопроса Что касается сути вопроса, то ответ я уже получил - использовать template'ы. Только надо будет это дело переварить
0
|
|
|
270 / 176 / 46
Регистрация: 12.03.2010
Сообщений: 494
|
|
| 21.11.2010, 16:36 | |
|
На возможностях старого стандарта это сделать достаточно трудно, чтобы любую функцию запустить в отдельном потоке, а возможности нового стандарта пока не трогал, потому как не все еще используют поддерживающие их компиляторы. Из готовых решений есть Proactor
0
|
|
|
|
|||
| 21.11.2010, 16:53 [ТС] | |||
|
0
|
|||
|
270 / 176 / 46
Регистрация: 12.03.2010
Сообщений: 494
|
||||||
| 21.11.2010, 17:00 | ||||||
|
В каждом конкретном случае описывать такой себе ThreadDummy действительно просто, но сделать универсальный обьект для разнотипных функций с переменным числом параметров - тяжко на старых возможностях. Тот шаблон что я выставил можно немного переделать и сделать просто внутреннюю функцию потока, внутри которой будет вызываться переданная ей функция и колбек в конце.
0
|
||||||
|
|
||
| 21.11.2010, 17:36 [ТС] | ||
|
0
|
||
|
|
||||||
| 15.04.2011, 19:49 [ТС] | ||||||
|
Итого по ходу дела я нашёл решение для своего вопроса. Мне это нужно было для Borlnad'а, а у Borland'а есть ацкое расширнеие __closure: http://www.goforvbsix.ru/news/... -01-21-385 По ссылке текст корявый (переведён автоматическим переводчиком), но суть следующая. Если объявить указатель на функцию с модификатором __closure, то такой "указатель" будет содержать в себе на самом деле два указателя: указатель на метод и указатель на экземпляр класса в момент присваивания. Что важно, указатель на метод и указатель на экземпляр класса обезличенные: т.е. никакой информации о конкретном типе нет, а потому такую конструкцию можно протащить через транзитный код. В точке вызова по такому указателю компилятор выдерет из него адрес функции и ажрес экземпляра (по сути дела this) и по своим внутренним правилам построит вызов метода. Именно в этом месте и хранится невозможность использования данной фичи в виде обезличенных двух указателей на void, потому что после этого на языке нет возможности описать вызов метода без подпольных знаний о том, как это делает компилятор. Насколько я понимаю, подобной конструкции в языке Си++ нет, а жаль.
Я ещё не проверял, просто вывел сие из корявых описаний и объяснений на форумах. Надеюсь, что я понял всё-таки правильно Добавлено через 2 часа 3 минуты С этой конструкцией код будет выглядеть так:
0
|
||||||
|
Делаю внезапно и красиво
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
|
|
| 16.04.2011, 12:45 | |
|
А если вместо указателя на метод передавать функтор? В нём можно и this "точно правильный" передать.)
0
|
|
|
|
||
| 16.04.2011, 14:01 [ТС] | ||
|
Если я что-то не так понимаю, то перепиши код из поста #18 с использованием функтора. Для меня важно, чтобы внутренности класса Base НЕ являлись открытыми (т.е. не были шаблоном и не были описаны внутри описания класса)
0
|
||
| 16.04.2011, 14:01 | |
|
Помогаю со студенческими работами здесь
20
Переопределение виртуального метода переопределение виртуального метода Ошибка создания виртуального метода? Реализовать перегрузку виртуального метода Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
||||
|
Учёным и волонтёрам проекта «Einstein@home» удалось обнаружить четыре гамма-лучевых пульсара в джете Млечного Пути
Programma_Boinc 01.01.2026
Учёным и волонтёрам проекта «Einstein@home» удалось обнаружить четыре гамма-лучевых пульсара в джете Млечного Пути
Сочетание глобально распределённой вычислительной мощности и инновационных. . .
|
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Налог на собак: https:/ / **********/ gallery/ V06K53e
Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf
Пост отсюда. . .
|
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop?
Ниже её машинный перевод.
После долгих разбирательств я наконец-то вернула себе. . .
|
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод
Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод.
Thinkpad X220 Tablet —. . .
|
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта
Симптом:
После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
|
|
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
|
Новый ноутбук
volvo 07.12.2025
Всем привет.
По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне:
Ryzen 5 7533HS
64 Gb DDR5
1Tb NVMe
16" Full HD Display
Win11 Pro
|
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
|
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
|
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов
На странице:
https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/
нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
|