![]() |
Модераторы: Daevaorn |
![]() ![]() ![]() |
|
Нитонисе |
|
||||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 917 Регистрация: 5.11.2009 Репутация: нет Всего: 2 |
Пишу класс
Этот код конечно не работает, просто что бы пояснить чего я хочу. А хочу я иметь членом класса некую функцию func, реализация которой может быть произвольной. Ну вот например:
Как это сделать? |
||||
|
|||||
EvilsInterrupt |
|
||||
Executables research ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1019 Регистрация: 14.7.2007 Где: Железнодорожный, МО, Россия Репутация: 2 Всего: 9 |
Нитонисе,
1)
Это верно? Если оформить по красивее, то:
2) Почему в setFunc присваиваете в переменную "void *func;", а в DoFunc() дергаете какую-то мифическую f() ? 3) Может Вам изучить понятие "функтор" ? Другие названия этого термина "Объект функции". Это класс с переопределенным оператором "круглые скобки", чтобы объект этого класса вел себя как функция. Т.е. "все что выглядит как функция, ведет себя как функция = есть функция" |
||||
|
|||||
Нитонисе |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 917 Регистрация: 5.11.2009 Репутация: нет Всего: 2 |
С оформлением я не заморачивался, потому как писал прямо в форме ответа. Соответственно и опечатку в DoFunc допустил. А вот по п.3 видно надо изучать матчасть.
|
|||
|
||||
NoviceF |
|
||||||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 313 Регистрация: 13.3.2012 Где: Ростов-на-Дону Репутация: нет Всего: 2 |
что-то похожее на то, что ты хочешь, есть в паттерне "Стратегия" http://ru.wikipedia.org/wiki/%D0%A1%D1%82%...BD%D0%B8%D1%8F) вот кусок кода оттуда
в моём понимании произвольной может быть реализации, но интерфейс должен быть фиксированным. В случае с функцией, фиксированной должна быть сигнатура. Ну то есть здесь
void *func; должен быть указателем на какую-то конкретную сигнатуру, и присваивать ему мы дожны функции с такой же сигнатурой, но, если требуется, различным поведением. Хотя на практике не сталкивался, но по идее должно работать ![]() Это сообщение отредактировал(а) NoviceF - 4.1.2013, 16:09 |
||||||
|
|||||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
понятие функция может быть легко расширено до функционального обьекта и это расскрывает новые свободы, о чeм уже было сказано выше.. для ознакомления с подобной концепцией см. [boost:: / (c++11)std::] function и bind.. Добавлено через 2 минуты и 16 секунд
для простой функции никаких наворотов не требуется, всe работает из коробки ) |
|||
|
||||
EvilsInterrupt |
|
|||
Executables research ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1019 Регистрация: 14.7.2007 Где: Железнодорожный, МО, Россия Репутация: 2 Всего: 9 |
Нитонисе,
Поясни какую проблему ты решаешь? Для чего потребовался такой код? Возможно есть решение проще. |
|||
|
||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
вот набросок :
|
|||
|
||||
NoviceF |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 313 Регистрация: 13.3.2012 Где: Ростов-на-Дону Репутация: нет Всего: 2 |
![]() |
|||
|
||||
EvilsInterrupt |
|
|||
Executables research ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1019 Регистрация: 14.7.2007 Где: Железнодорожный, МО, Россия Репутация: 2 Всего: 9 |
NoviceF,
По моему никнейму поищи недавнюю тему, которую я создал. В ней про функторы достаточно много рассказано |
|||
|
||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
глянуть хотя бы на стл :
http://liveworkspace.org/code/409lqK$0 Добавлено через 3 минуты и 54 секунды если вместо 10 и 15 поставить переменные, то реализовать подобное через указатели на функции будет затруднительно.. Добавлено через 6 минут и 52 секунды ну а с лямбдой, как дальнейшее развитии функтора, выглядит еще удобнее : http://liveworkspace.org/code/409lqK$2 Добавлено через 9 минут и 31 секунду ну и с замыканием контекста : http://liveworkspace.org/code/409lqK$3 все это приведенно на скорую руку, на самом деле преимущества гораздо шире ) |
|||
|
||||
EvilsInterrupt |
|
|||
Executables research ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1019 Регистрация: 14.7.2007 Где: Железнодорожный, МО, Россия Репутация: 2 Всего: 9 |
mes,
Я бы предпочел так оформить код:
Понятней как-то... ) |
|||
|
||||
NoviceF |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 313 Регистрация: 13.3.2012 Где: Ростов-на-Дону Репутация: нет Всего: 2 |
Спасибо за примеры, но представление о функторах и лямбдах я имею
![]() Это сообщение отредактировал(а) NoviceF - 4.1.2013, 23:47 |
|||
|
||||
EvilsInterrupt |
|
|||
Executables research ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1019 Регистрация: 14.7.2007 Где: Железнодорожный, МО, Россия Репутация: 2 Всего: 9 |
NoviceF,
Польза от использования функторов в том что это объекты! А объекты имеют состояние. То есть перед подачей объекта куда-либо ты можешь его про инициализировать, а после того как это "куда-либо" отработало ты еще можешь прочитав его состояние знать результат какой-угодно тебе. Рекомендую книгу Джосьютиса "Стандартная библиотека C++". Сам читаю, очень опечален тем что раньше ее не прочитал ((( |
|||
|
||||
NoviceF |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 313 Регистрация: 13.3.2012 Где: Ростов-на-Дону Репутация: нет Всего: 2 |
спасибо, учту.
хороших книжек много и читаю я их не быстро ![]() |
|||
|
||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
![]() по данному классу сказать проблематично, так как требования по задаче не сформурлированы, а я увы не телепат ![]()
грубо говоря, да ![]() ![]() Это сообщение отредактировал(а) mes - 5.1.2013, 04:07 |
|||
|
||||
EvilsInterrupt |
|
|||
Executables research ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1019 Регистрация: 14.7.2007 Где: Железнодорожный, МО, Россия Репутация: 2 Всего: 9 |
NoviceF,
Забыл сказать о "лямбда". Если Вы помните, что в C++03 нужно писать так:
В случае использования "лямбда", доступных в C++11, когда Вы знаете что ваша_кустом_функция очень маленькая, то Вы можете написать ее код, но без указания ее имени. Это удобно тем что 1) читающий код будет меньше скролить экран в другое место, чтобы увидеть реализацию, т.е. чтение кода будет более эффективным. 2) сокращает набор текста, а программистам же так не нравится много писать |
|||
|
||||
mes |
|
||||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
![]()
почти.. по кол-ву символов выходит также.. программистам не нравится выдумывать имена одноразовых функций )) и еще кое что забыто, из за того что начали сравнивать лямбду с функцией, позабыв про бинд.. самое важное свойство - это замыкание контекста )) ибо локальную функцию (чтоб не скролить) с небольшой избыточностью, можно получить и без лямбды.. |
||||
|
|||||
NoviceF |
|
||||||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 313 Регистрация: 13.3.2012 Где: Ростов-на-Дону Репутация: нет Всего: 2 |
это же синтаксис и пример использования обычной функции в алгоритме STL? лямбду я понимаю как нечто
Это для случая:
спасибо Борису (borisbn) ![]() конечно, возможен и вариант использования лямбды в роли предиката. вот об это не слышал, почитал вику, там как пример замыкания приводятся опять таки лямбда функции. Но в целом смысл понятен. Удобно, что лямбда может обращаться к внешним переменным, в том числе и по ссылке. |
||||||
|
|||||||
mes |
|
||||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
лямбда на самом деле нечто большее )) если с замыканием она "анологична" функтору, то без контекста - обычной функции.. и ее легко можно использовать для адаптации сигнатуры :
http://liveworkspace.org/code/4xodmZ$0 Добавлено @ 17:05 то есть, в лямбде сильна не только ее анонимность, а таже ее конвертибельность, при отсутствии (ненужного) оверхеда.. Добавлено @ 17:10 вот еще один примерчик с лямбдами как с-функции:
http://liveworkspace.org/code/3tkd17$0 Это сообщение отредактировал(а) mes - 5.1.2013, 17:11 |
||||
|
|||||
NoviceF |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 313 Регистрация: 13.3.2012 Где: Ростов-на-Дону Репутация: нет Всего: 2 |
головокружительные пируэты ![]() Добавлено @ 17:15 просветите, что за синтаксис? отбой, нашёл в вики. Надо всётаки когда-нибудь дочитать список "нововведений" в с++11.. где тут смайлик *слоупок*.. Это сообщение отредактировал(а) NoviceF - 5.1.2013, 17:19 |
|||
|
||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
||||
|
||||
NoviceF |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 313 Регистрация: 13.3.2012 Где: Ростов-на-Дону Репутация: нет Всего: 2 |
Отличная вещь.. осталось только подружить qnx Momentics с gcc 4.7.. ![]() |
|||
|
||||
Нитонисе |
|
||||||||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 917 Регистрация: 5.11.2009 Репутация: нет Всего: 2 |
В развитие темы
![]() Я тут попробовал набросать пример по наводке mes. Пишу в RAD Studio Builder XE, но думаю для данной задачи это не принципиально, просто код билдеровский. Вот класс
Вот заголовочный файл формы в билдере
Вот применение моего тестового класса
Ошибка компилятора
Это чего он от меня хочет? ![]() ![]() |
||||||||
|
|||||||||
bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
Нитонисе, во-первых, указатель на метод класса несколько иначе записывается.
во-вторых, адрес метода класса берется тоже несколько иначе в-третьих, а какое отношение данный вопрос имеет к обсуждаемой теме? С указателем на функцию в качестве члена класса у тебя проблем нет. |
|||
|
||||
Нитонисе |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 917 Регистрация: 5.11.2009 Репутация: нет Всего: 2 |
Такое отношение, что я пока не разобрался как это сделать. Мне нужно в свой класс в разные моменты времени подсовывать разные функции других классов. Вот как в этом простом примере я передаю указатели на функции класса формы. |
|||
|
||||
NoviceF |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 313 Регистрация: 13.3.2012 Где: Ростов-на-Дону Репутация: нет Всего: 2 |
||||
|
||||
Нитонисе |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 917 Регистрация: 5.11.2009 Репутация: нет Всего: 2 |
Да, будут. Я делаю класс контролирующий открытие/закрытие/сохранение файла. На форме есть набор компонентов, их состояние можно сохранить в файл, либо загрузить из файла. У разных программ будет разный набор этих оконных компонентов, куда будут загружаться данные. Соответственно разная будет реализация функций Load и Save. Но они будут обращаться к данным класса формы. |
|||
|
||||
bsa |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
Нитонисе, в стандарте С++ указатели на методы класса очень специфичные (я бы сказал - практически бесполезные субстанции). В Борландовской реализации есть более грамотные указатели (несут в себе не только указатель на сам код, но и на объект класса). Для их использования необходимо применять ключевое слово __closure. Поищи документацию во встроенной справке. Там все есть.
Если же тебе хочется работать со стандартными указателями на метод, то делается это так:
Добавлено @ 13:25
А вот если программа одна, а "формы разные", то да, возможно ты мыслишь в правильном направлении. Но опять же. Не совсем. В Билдере есть уже для этого все что нужно. назначь на onClick вызов нужного метода нужного класса и все. |
||||
|
|||||
Нитонисе |
|
||||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 917 Регистрация: 5.11.2009 Репутация: нет Всего: 2 |
bsa
Я заметил, что у меня от программы к программе копируется код по работе с файлом практически один в один, за исключением функций Load и Save. Поэтому и родилась идея все это привести к единому знаменателю. А какой OnClick предлагается обрабатывать - я не понял. Если имеется ввиду нажатие на кнопку открывающую/закрывающую файл - то конечно это сделать можно, но работа с файлом заключается не только в открытии и сохранении. Там еще контролируется состояние изменения, проверка корректности данных при открытии, при сохранении, вобщем есть ряд действий, которые одинаковы из программы в программу. |
||||
|
|||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
Нитонисе, посмотрите в доке (вот опять очередная отсылка
![]() |
|||
|
||||
bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
исправил
|
|||
|
||||
Нитонисе |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 917 Регистрация: 5.11.2009 Репутация: нет Всего: 2 |
||||
|
||||
bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
Нитонисе, использование указателей на методы - это обычно всегда плохая идея. Чаще всего, они используются для реализации каких-нибудь "улучшайзеров" языка. Например, boost::bind (или std::bind), boost::function (std::function) и пр. В обычной жизни в них потребность крайне низка. И если вдруг тебе пришла в голову идея их использовать, подумай еще разик, может лучше подойдет наследование или шаблоны?
|
|||
|
||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
особенно, когда есть улучшайзеры )) вон и борланда они есть.. только кому лень в доку глянуть )) ..так и придется всю жизнь наследоваться... и проклинать наследование и ооп, как только встретится задача с "перехлестыванием интерфейсов" )) а раз пошли держать путь на модульность встретится и довольно скоро )) Добавлено через 1 минуту и 10 секунд ![]() |
|||
|
||||
![]() ![]() ![]() |
Правила форума "С++:Общие вопросы" | |
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |