Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > C/C++: Общие вопросы > Передача функции или метода в кач-ве параметра |
Автор: nerezus 30.4.2007, 18:51 |
Есть некоторый класс. В одном из его методов он должен принимать функцию, в другом вызывать ее. 1) Функция. Она всегда имеет параметры определенного типа. Допустим структуру st. Один из методов моего класса получает эту функцию(как?) и запоминает в свойство(с каким типом?), а другой метод вызывает ее(как?) с параметром в виде структуры. 2) То же самое, но с методом объекта, а не с функцией. Класс объекта заранее не известен. |
Автор: archimed7592 30.4.2007, 19:13 | ||
для метода:
совет тебе добрый: многим лучше использовать обощённые функторы... |
Автор: Greeen 30.4.2007, 19:15 | ||
|
Автор: Mayk 30.4.2007, 19:17 | ||||
А учитывая
то другого приемлимого выхода собственно и не остаётся. |
Автор: nerezus 30.4.2007, 19:24 | ||||||||
Спасибо, заработало:
А про методы ничего нету? )
Добавлено через 2 минуты и 55 секунд оо, сколько ответов.
Добавлено через 6 минут и 11 секунд
|
Автор: archimed7592 30.4.2007, 19:41 |
boost::bind, boost::lambda, Loki::Function... а вообще читай Александрску, Современное проектирование на С++ ![]() функторы ![]() в двух словах - это объекты у которых перегружен operator () |
Автор: nerezus 30.4.2007, 19:44 |
хм, тогда остается 2 варианта: 1) наследование нужного класса, из которого я хотел делать вызовы. Но тут проблемы, ибо он у меня Singleton 2) Strategy паттерн, но как-то хреново я его тут представляю.... |
Автор: archimed7592 30.4.2007, 19:57 | ||||
3) использовать функторы ![]() скажи, а в чём проблема их использовать? ![]() компилировать boost для них не нужно, если не ошибаюсь... пример...вот те простейший пример:
Добавлено через 3 минуты и 2 секунды кстати, для map ты видишь как производится доступ к членам (полям/методам)... функтор возвращённый boost::bind можно засунуть, скажем, в boost::function (или Loki::Function) и вызывать не зная ни класса, ни метода... ничего... |
Автор: archimed7592 30.4.2007, 21:09 | ||
про возможности http://boost.org/libs/bind/bind.html про возможности http://boost.org/doc/html/lambda/le_in_details.html (не встречавшим конструкций if_then/try_catch и т.п. рекомендую - сильно впечатляет в первый раз ![]() про возможности http://boost.org/doc/html/function/tutorial.html nerezus, конкретно твоя задача решается примерно так:
|
Автор: nerezus 30.4.2007, 21:20 |
Блин, как-то некрасиво получается =\ Я вот думаю, может стоит попытаться заюзать готовый фреймворк? Просто ща я пытался структурный код SDL переделать в ООП(при практически нулевых знаниях С++) и столкнулся с сабжем. Добавлено через 1 минуту и 2 секунды archimed7592, за код спасибо. А можешь выложить либы буста для этого примера? |
Автор: Любитель 30.4.2007, 23:04 |
nerezus, ты просто не почувствовал красоты в понятии плюсов ![]() На мой взгляд, буст (и особенно бустовское ФП) - это самое красивое в плюсах ![]() |
Автор: nerezus 30.4.2007, 23:13 | ||||
|
Автор: archimed7592 30.4.2007, 23:15 | ||
Любитель, всецело и полностью согласен ![]() ![]() nerezus,
![]() если нужен сам буст, то на http://boost.org тебе дорога... Добавлено через 2 минуты и 26 секунд нет, map к функциональному программированию отношения не имеет ![]() скажи для начала в каких языках есть такие же мощные средства для ФП ![]() ![]() |
Автор: Любитель 30.4.2007, 23:23 |
Всё-таки позволю не согласиться... Прикол плюсов в достаточно виртуозной реализации многих вещей (не только ФП) без явной поддержки этого со стороны языка. Это красиво. В определённом роде. Добавлено через 1 минуту и 34 секунды Питон - это хороши, интересно... Но красоты я лично не вижу. Не привлекает. А програмерить на плюсах - приятно, блин! |
Автор: archimed7592 30.4.2007, 23:27 |
с чем несогласен то? насчёт прикола плюсов: это не прикол... это само совершенство... ;) Добавлено через 57 секунд ага... люблю этот язык ![]() |
Автор: Любитель 30.4.2007, 23:29 |
Не соглашусь, что на языках с нэтивной поддержкой ФП невозможно писать. Можно и очень хорошо. На некоторых даже интересно. Но плюсы - не знаю, лично мне всё-таки нравиться дизайн и философия языка. Недоделан он, конечно, но, блин, хорош... |
Автор: Mayk 30.4.2007, 23:38 | ||||
Уж если буст тянуть, то можно черезhttp://www.boost.org/doc/html/signals/tutorial.html#id2731274 связь с SDL сделать. Примерно так:
|
Автор: archimed7592 1.5.2007, 00:05 | ||
![]() |
Автор: Mayk 1.5.2007, 00:09 | ||
![]() ![]() |
Автор: Любитель 1.5.2007, 00:11 |
![]() Насчёт boost::signals - немного недоделана либа: 1. Хорошо бы иметь возможность паблик-доступа на коннект и прайват - на вызов. Или типа того. 2. Очень неприятно упоминание о потонебезопасности в доках по либе ![]() |
Автор: Mayk 1.5.2007, 00:26 | ||||
набросочно это можно решить так:
|
Автор: Ken 1.5.2007, 00:51 | ||||||||||
Nerezus, почему не хотите использовать event listener-ы в стиле Java? Это проще и не требует темплейтов и доп. библиотек. Например, допустим, вы создаете компонент Button. Хотите от него получить событие onClick (). Просто объявляем новый абстрактный класс (interface):
А к классу Button добавляем метод и член:
Класс который хочет ловить событие onClick () должен наследовать от ButtonListener и реализовать метод onClick (). А внутри одного из методов Button генерация onClick будет выглядеть так:
Регистрация обработчика уже будет выглядеть примерно как вы хотите:
|
Автор: Любитель 1.5.2007, 08:49 |
Mayk, ну я немного по другому делаю - у меня шаблон для сигналов (юзающий бустовские, конечно) с дополнительным параметром - классом, для которого разрешён вызов сигнала. Насчёт ивент-листенеров - в яве есть анонимные классы, в плюсах нет. Потому юзать ивент-листенеры наглой копией - не очень приятно. К тому же пропадает возможность биндинга и пр. приятных вещей. |
Автор: Ken 1.5.2007, 09:07 | ||
Что означает "юзать ивент-листенеры наглой копией"? Не обязательно использовать анонимных классов. Если количество объектов от которых можем получать событий не очень много, то один класс-контроллер отвечающий за логику приложения бывает достаточным, если много, то можно создавать разные контроллеры обрабатывающие события. Мне нравится простота и эффективность этой схемы, она работает без дополнительных затрат (зачем boost, особенно в встроенных системах только из за этого). |
Автор: nerezus 1.5.2007, 10:30 | ||||||
Ken, оо, самый лучший совет ) Просто это со стороны структурного кода работать не будет, ну да ладно, ну первую часть нафиг. Спасибо. В C++ можно же при наследовании от 2х классов тип указателя на Child сделать указателем на Parent1(лисенер)? Ну вот и лучший вариант ) |
Автор: Любитель 1.5.2007, 11:35 |
В пиноте нэтив-роддержка. А в плюсах красивая эффектная реализация. ![]() Я не говорю, что обязательно, но без них очень неудобно. Бустовские вещи в данном случае гораздо более гибкое и красивое решение (boost::function, boost::signal, boost::bind, boost::lambda). + действительно в стиле плюсов. |
Автор: Ken 1.5.2007, 12:29 | ||||||
Согласен с вами. Но программируя часто для встроенных систем и микроконтроллеров совсем неприятно увидеть как твой продукт становиться раздутым из за разных библиотек, поэтому если можно обойтись без них, то лучше использовать простые средства которые решают задачу. В любом случае нет ничего абсолютно классного, это одно из решений, для меня оно всегда работало эффективно.
Nerezus для струрного кода используйте указателей на функций как в начале показали товарищи.
Да. Это то же самое что реализация интерфейсов в Java (если все методы второго класса абстракные и класс не содержит свои поля). Можете наследовать не только от 2х ;) |
Автор: Любитель 3.5.2007, 18:25 | ||
[offtop]Почему с нами?[/offtop]
Не знаю. Встроенные системы, микроконтроллеры - ничем этим не занимаюсь ![]() + для многих ситуаций хватит STL-вского ФП. Впрочем, дело вкуса, конечно. |
Автор: archimed7592 4.5.2007, 14:39 |
что за ситуации такие? ![]() я так понимаю речь о bind1st/2nd ![]() ![]() |
Автор: Любитель 7.5.2007, 12:14 |
Прод стл-вским ФП (в отличие от бустовского - его развития) я понимаю: 1. std::unary_function и пр. вместо boost::function. 2. std::bind1st и пр. вместо boost::bind. 3. std::map + первый пункт вместо boost::signals ![]() 4. Повеситься вместо boost::lambda ![]() |
Автор: archimed7592 7.5.2007, 13:06 |
м. б. std::deque? ![]() то то и оно ![]() ![]() |
Автор: Любитель 7.5.2007, 13:17 |
Туплю. Думал нужна привяка от строк - не нужна ![]() |