|
|
|||||||||||
Использование указателя на метод вместо виртуального метода20.11.2010, 12:33. Показов 7070. Ответов 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
Переопределение виртуального метода переопределение виртуального метода Ошибка создания виртуального метода? Реализовать перегрузку виртуального метода Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
Автозаполнение реквизита при выборе элемента справочника
Maks 27.03.2026
Программный код из решения ниже на примере нетипового документа "ЗаявкаНаРемонтСпецтехники" разработанного в конфигурации КА2.
При выборе "Спецтехники" (Тип Справочник. Спецтехника), заполняется. . .
|
Сумматор с применением элементов трёх состояний.
Hrethgir 26.03.2026
Тут.
https:/ / fips. ru/ EGD/ ab3c85c8-836d-4866-871b-c2f0c5d77fbc
Первый документ красиво выглядит, но без схемы.
Это конечно не даёт никаких плюсов автору, но тем не менее. . . всё может быть. . .
|
Автозаполнение реквизитов при создании документа
Maks 26.03.2026
Программный код из решения ниже размещается в модуле объекта документа, в процедуре "ПриСозданииНаСервере".
Алгоритм проверки заполнения реализован для исключения перезаписи значения реквизита,. . .
|
Команды формы и диалоговое окно
Maks 26.03.2026
1. Команда формы "ЗаполнитьЗапчасти".
Программный код из решения ниже на примере нетипового документа "ЗаявкаНаРемонтСпецтехники" разработанного в конфигурации КА2.
В качестве источника данных. . .
|
|
Кому нужен AOT?
DevAlt 26.03.2026
Решил сделать простой ланчер
Написал заготовку:
dotnet new console --aot -o UrlHandler
var items = args. Split(":");
var tag = items;
var id = items;
var executable = args;. . .
|
Отправка уведомления на почту при изменении наименования справочника
Maks 24.03.2026
Программная отправка письма электронной почты на примере изменения наименования типового справочника "Склады" в конфигурации БП3. Перед реализацией необходимо выполнить настройку системной учетной. . .
|
модель ЗдравоСохранения 5. Меньше увольнений- больше дохода!
anaschu 24.03.2026
Теперь система здравосохранения уменьшает количество увольнений.
9TO2GP2bpX4
a42b81fb172ffc12ca589c7898261ccb/
https:/ / rutube. ru/ video/ a42b81fb172ffc12ca589c7898261ccb/
Слева синяя линия -. . .
|
Midnight Chicago Blues
kumehtar 24.03.2026
Такой Midnight Chicago Blues, знаешь?. .
Когда вечерние улицы становятся ночными, а ты не можешь уснуть. Ты идёшь в любимый старый бар, и бармен наливает тебе виски. Ты смотришь на пролетающие. . .
|