Название: Делегаты С++ в классах-наследниках Отправлено: Fregloin от Декабрь 26, 2014, 16:14 Привет, кто то сталкивался с делегатами в с++ и как их использовать в наследуемых классах?
Нашёл пока только описание толковое для делегатов одного класса. С наследованием проблемы... По сути что надо. Есть класс базовый Код: class Base { описана сигнатура делегата, а также хеш в котором они будут храниться и вызываться по имени. Сами делегаты должны быть реализованы в наследуемых классах. В этом и проблема, что с данной сигнатурой я могу регистрировать делеагты созданные в базовом классе, а с наследником уже не получается. Либо через reinpret_cast<BaseClass::delegate>. Тогда вызываемый делегат наследника видит только ту часть объекта, которая соответствует классу Base. Знаю что есть подобній функционал в boost, но я не хочу его за собой тянуть (ради одной функции тянуть все зависимости). Название: Re: Делегаты С++ в классах-наследниках Отправлено: Igors от Декабрь 26, 2014, 18:12 Ладно, не постесняюсь спросить :) А разве "делегат" какой-то стандартный термин в плюсах? (никогда не слышал о таком). По тексту я вижу просто указатель на ф-цию член. Если в базовом классе она не виртуальна - получите именно то что описываете
Название: Re: Делегаты С++ в классах-наследниках Отправлено: _Bers от Декабрь 26, 2014, 20:26 Ладно, не постесняюсь спросить :) А разве "делегат" какой-то стандартный термин в плюсах? Да. см std::function Название: Re: Делегаты С++ в классах-наследниках Отправлено: m_ax от Декабрь 26, 2014, 22:04 Если я правильно понял, чего хочет ТС, то придётся шагнуть чуть дальше, чем просто std::function)
Название: Re: Делегаты С++ в классах-наследниках Отправлено: Igors от Декабрь 27, 2014, 09:45 Да. Смотрю http://www.cplusplus.com/reference/functional/function/ (http://www.cplusplus.com/reference/functional/function/), слова "delegate" там нет. Ладно, не суть "как называется", поясните какой смысл вкладывается здесь в этот терминсм std::function Спасибо Название: Re: Делегаты С++ в классах-наследниках Отправлено: Johnik от Декабрь 28, 2014, 00:12 На RSDN есть статья "Указатели на функции-члены и реализация самых быстрых делегатов на С++." (http://www.rsdn.ru/article/cpp/fastdelegate.xml)
Если я не ошибаюсь, там решался этот вопрос: В этом и проблема, что с данной сигнатурой я могу регистрировать делеагты созданные в базовом классе, а с наследником уже не получается. Название: Re: Делегаты С++ в классах-наследниках Отправлено: _Bers от Декабрь 28, 2014, 00:49 поясните какой смысл вкладывается здесь в этот термин Делегат - средство опосредованного вызова функции, либо функции-члена. Обычно, с возможностью биндинга аргументов, с которыми нужно выполнить вызов. Область применения: организация callback вызовов в условиях, когда механизму-отправителю изначально не известен механизм-получатель сообщений. При помощи делегатов реализуются технологии "системы сообщений", "слоты-сигналы" и тп. Пример: http://rextester.com/VASRI32220 Код: #include <iostream> Название: Re: Делегаты С++ в классах-наследниках Отправлено: _Bers от Декабрь 28, 2014, 00:56 Если я правильно понял, чего хочет ТС, то придётся шагнуть чуть дальше, чем просто std::function) Если я правильно понял ТС, то он изобретает именно std::function. Он не хочет цеплять boost::function, потому что не хочет тащить буст. Однако, видимо он просто не в курсе, что boost::function официально узаконили. И он вошел в стандарт с++11 Теперь он доступен, как std::function. Название: Re: Делегаты С++ в классах-наследниках Отправлено: Igors от Декабрь 28, 2014, 13:39 Код: //заряжаем делегат. Название: Re: Делегаты С++ в классах-наследниках Отправлено: _Bers от Декабрь 28, 2014, 15:41 Т.е. в обоих случаях адрес model хранится в структуре function которая умеет вызывать и ф-цию-член? std::function - тонкая обертка над функторами. Она хранит объект-функтор по значению. А уже функтор может хранить адрес объекта, для которого нужно вызвать функцию-член, или сам этот объект по значению, или смарт поинтер на этот объект, или... В общем, вы можете скормить std::function любой функтор, какой захотите. Главное - что бы его operator() отвечал сигнатуре функции. Пример: http://rextester.com/DKA83721 Код: #include <iostream> Но обычно никто кастомные функторы не делает. В основном используют std::bind, который при помощи шаблонной магии генерирует функтор заточенный под вызов для конкретного объекта При этом объект можно сохранять по ссылке/значению/смарт-поинтер (насчет смарта не уверен). Ну лямбда - это понятно, это функтор который будет делать то, что вы сами там пропишите. Название: Re: Делегаты С++ в классах-наследниках Отправлено: Igors от Декабрь 29, 2014, 11:48 В основном используют std::bind, Да, с bind хорошо. А вот этот сам "объект-функтор" - он "физически" существует, или это темплейт-подстава? (наверное подстава). Напр нет С++ 11, как самостоятельно получить тот же ф-ционал? (просто с целью уяснить)который при помощи шаблонной магии генерирует функтор заточенный под вызов для конкретного объекта Спасибо Название: Re: Делегаты С++ в классах-наследниках Отправлено: Johnik от Декабрь 29, 2014, 12:12 Напр нет С++ 11, как самостоятельно получить тот же ф-ционал? повторюсь:На RSDN есть статья "Указатели на функции-члены и реализация самых быстрых делегатов на С++." (http://www.rsdn.ru/article/cpp/fastdelegate.xml) Название: Re: Делегаты С++ в классах-наследниках Отправлено: Igors от Декабрь 29, 2014, 12:26 повторюсь: И что? Все должны читать много страниц довольно субъективного текста, еще и почти десятилетней давности? :)На RSDN есть статья "Указатели на функции-члены и реализация самых быстрых делегатов на С++." (http://www.rsdn.ru/article/cpp/fastdelegate.xml) Название: Re: Делегаты С++ в классах-наследниках Отправлено: Johnik от Декабрь 29, 2014, 12:35 И что? Все должны читать много страниц довольно субъективного текста, еще и почти десятилетней давности? :) А как вы хотели что-то узнать не читая?Почитайте исходники того же std::function, общее представление может дать, не смотря на наличие С++11, но опять же там тоже много текста. Название: Re: Делегаты С++ в классах-наследниках Отправлено: Fregloin от Декабрь 29, 2014, 12:39 печально, но в моей версии 5.3.2 std::function не нашлось :(
Название: Re: Делегаты С++ в классах-наследниках Отправлено: Fregloin от Декабрь 29, 2014, 13:00 Ладно упрощу вопрос:
Есть базовый класс Код: class CBaseClass { Есть наследованный класс Код: class CDerivedClass : public CBaseClass Что я хочу получить: что бы можно было регистрировать в хеше функции обработчики, и потом их вызывать по имени и эти функции видели данные всех классов от базового до текущего. К сожалению сейчас это все реализовано через статические функции-члены что не совсем удобно. По сути это замена switch оператора, только параметр строковый. т.е. функции обработчику соотвествует определенное название в виде строки, и когда она приходит, нужно вызвать соотвествующий член-функцию, передать ей параметр и что бы функция вызвалась в том классе, в котором она описана а не в базовом (когда все private_derived..data не видны). Название: Re: Делегаты С++ в классах-наследниках Отправлено: Johnik от Декабрь 29, 2014, 13:06 печально, но в моей версии 5.3.2 std::function не нашлось :( std::function, это не Qt, это стандартные либы C++Если у вас gcc добавьте опцию компилятора: -std=c++11 Если msvc то версия должна быть не меньше 2010 (в опциях ничего не надо добавлять). Название: Re: Делегаты С++ в классах-наследниках Отправлено: Fregloin от Декабрь 29, 2014, 13:10 в Qt редакторе при компиляции ругается и подчеркивает как ненайденный элемент.
Название: Re: Делегаты С++ в классах-наследниках Отправлено: Igors от Декабрь 29, 2014, 13:23 Что я хочу получить: что бы можно было регистрировать в хеше функции обработчики, и потом их вызывать по имени и эти функции видели данные всех классов от базового до текущего. По-моему не хватает только virtual. А как вы хотели что-то узнать не читая? Пример: указатель на ф-цию член. Тут все ясно - хранится адрес ф-ции (чуть по-другому для virtual). А что в случае std::function? Тоже хранится адрес ф-ции или только объекта или как? Вот Вы много читали, объясните pleaseПочитайте исходники того же std::function, общее представление может дать, не смотря на наличие С++11, но опять же там тоже много текста. Название: Re: Делегаты С++ в классах-наследниках Отправлено: Johnik от Декабрь 29, 2014, 13:29 в Qt редакторе при компиляции ругается и подчеркивает как ненайденный элемент. Какой компилятор?Пример: указатель на ф-цию член. Тут все ясно - хранится адрес ф-ции (чуть по-другому для virtual). А что в случае std::function? Тоже хранится адрес ф-ции или только объекта или как? тут описание и хорошие примеры:http://ru.cppreference.com/w/cpp/utility/functional/function Название: Re: Делегаты С++ в классах-наследниках Отправлено: Fregloin от Декабрь 29, 2014, 13:31 вот такой
Название: Re: Делегаты С++ в классах-наследниках Отправлено: Fregloin от Декабрь 29, 2014, 13:34 ага, прописал в mkspecs/win32-g++
QMAKE_CFLAGS = -std=c++11 собралось Название: Re: Делегаты С++ в классах-наследниках Отправлено: Johnik от Декабрь 29, 2014, 13:35 вот такой 1. я не уверен, но возможно там кавычки не нужны2. выполнить qmake можно в pro файл добавить строку: Код: gcc:QMAKE_CXXFLAGS += -std=c++11 Название: Re: Делегаты С++ в классах-наследниках Отправлено: Igors от Декабрь 29, 2014, 13:43 тут описание и хорошие примеры: Ну то я читал не раз, правда в чуть др редакции http://www.cplusplus.com/reference/functional/function/ (http://www.cplusplus.com/reference/functional/function/). Да. хорошее описание и примеры, вообще - прекрасный справочник. Но это "как юзать" - а я хотел узнать о внутреннем механизме. Ладно, "понял, отстал" :)http://ru.cppreference.com/w/cpp/utility/functional/function ага, прописал в mkspecs/win32-g++ Наверное можно и std::function, но и обычный указатель на ф-цию член (без С++ 11) должен работатьНазвание: Re: Делегаты С++ в классах-наследниках Отправлено: Fregloin от Декабрь 29, 2014, 13:47 обычный указатель на функцию-член работает только в классе, в котором он описан. В наследниках уже такое не прокатит, проверено.
Название: Re: Делегаты С++ в классах-наследниках Отправлено: Fregloin от Декабрь 29, 2014, 15:14 никак не могу разобраться с std::bind, std::function.
Нашёл простые примеры, но толку с них для меня не много. Вот что я пытаюсь сделать Код: class QRailItem; //графический элемент на сцене Теперь я объявляю наследника Код: class CDerivedController : public CBaseController Подскажите как правильно мне все сделать... Название: Re: Делегаты С++ в классах-наследниках Отправлено: Igors от Декабрь 29, 2014, 15:50 обычный указатель на функцию-член работает только в классе, в котором он описан. В наследниках уже такое не прокатит, проверено. Не раз использовал, работает. И должен работать - иначе зачем бы этот указатель имел поддержку вызова виртуалов (а он ее имеет)Название: Re: Делегаты С++ в классах-наследниках Отправлено: Fregloin от Декабрь 29, 2014, 16:47 Покажите пример, потому что я пробовал делать как вы говорите, не работает
Название: Re: Делегаты С++ в классах-наследниках Отправлено: Igors от Декабрь 29, 2014, 17:28 Покажите пример, потому что я пробовал делать как вы говорите, не работает Код
Название: Re: Делегаты С++ в классах-наследниках Отправлено: m_ax от Декабрь 29, 2014, 20:43 Выше всё уже показали же.. Это делается с помощью std::function + std::bind
Код
Название: Re: Делегаты С++ в классах-наследниках Отправлено: _Bers от Декабрь 29, 2014, 21:04 Да, с bind хорошо. А вот этот сам "объект-функтор" - он "физически" существует, или это темплейт-подстава? (наверное подстава). Напр нет С++ 11, как самостоятельно получить тот же ф-ционал? (просто с целью уяснить) Делегаты наподобие std::function можно завелосипедить самостоятельно. Это не сложно. Некоторое время назад, я изготавливал собственные велосипеды для с++03. Только у меня использовалась связка: динамика и статика. Статика работает по такому же принципу, что и std::function. Скорость вызова - такая же. Скорость бинда на порядок (в десять раз) быстрее, чем у стандартного аналога. Динамика работает на два порядка медленнее (в 100 раз дольше). Дизайн такой: Код: TConnector<R(int)> tcon(obj, &Some::Method); Суть динамического делегата в том, что не являясь продуктом шаблона, такие делегаты можно хранить в одном массиве, при этом нацеливать их можно куда угодно. Это делает динамический делегат очень удобным и быстрым решением, когда в статике ещё не известно на что придется нацеливаться делегату. Если вам это интересно, то мы можем подробно разобрать рецепт изготовления в рамка с++03. Название: Re: Делегаты С++ в классах-наследниках Отправлено: Fregloin от Декабрь 30, 2014, 12:59 Спасибо m_ax за доходчивый пример. Все хорошо кроме того что используются шаблоны, т.к. базовый класс у меня находится в отдельной библиотеке DLL, но вписав метод register_delegate в тело класса все собралось и заработало! Спасибо всем за пояснения, потому что честно говоря я с шаблонами не совсем дружу и редко их использую, а тут еще мудреные function bind ... :-\
Название: Re: Делегаты С++ в классах-наследниках Отправлено: Igors от Декабрь 30, 2014, 13:40 //--- обратите внимание: динамический делегат не является продуктом шаблона Да, интересно (не представляю как/куда Вы спрячете тип). А без (долбаных) шаблонов - вообще прекрасно!Если вам это интересно, то мы можем подробно разобрать рецепт изготовления в рамка с++03. Спасибо Название: Re: Делегаты С++ в классах-наследниках Отправлено: m_ax от Декабрь 30, 2014, 21:32 Цитировать Да, интересно (не представляю как/куда Вы спрячете тип). А про полиморфизм не слышали? Цитировать А без (долбаных) шаблонов - вообще прекрасно! И (долбаные) шаблоны там всё равно будут.. И откуда такие комплексы по поводу них?) |