![]() |
Модераторы: Daevaorn |
![]() ![]() ![]() |
|
EvilsInterrupt |
|
|||
Executables research ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1019 Регистрация: 14.7.2007 Где: Железнодорожный, МО, Россия Репутация: 2 Всего: 9 |
Есть код:
Я ожидаю что передавая объект, автоматически вызовется operator(). Мне нужно чтобы класс парсера вызвал этот оператор, а тот в свою очередь поменял состояние объекта,запомнив переданную ошибку. Прав ли я? Или все не так просто и функтор не может менять состояние объекта? Если да, то мне похоже нужно юзать static метод, а в нем писать либо статическую переменную или обращение к синглтону или другую магию... |
|||
|
||||
volatile |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 37 Всего: 85 |
Здесь это не причем. Вы передаете ему копию объекта, вот состояние этой копии он и меняет. Здесь 2 пути. либо передавать ему ссылку на объект, либо копию объекта хранящуюся в парсере считать основной. Выбор способа зависит от логики вашей программы (чтото здесь советовать трудно, т.к. мало информации.) 1-ый способ:
2-ой способ:
Во 2-ом случае, нужно будет дать доступ к объекту Parser::errHandler, либо геттером, либо явно, переместив его в паблик. Это сообщение отредактировал(а) volatile - 7.12.2012, 12:17 |
||||
|
|||||
volatile |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 37 Всего: 85 |
Я не заметил что у вас в парсере хранится не объект, а указатель на функцию. Зачем? operator(), имеет совсем другую сигнатуру. вам нужно хранить либо указатель на сам объект ErrorHadler, либо ссылку на него. (что я и предложил в 1-ом способе) |
|||
|
||||
volatile |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 37 Всего: 85 |
Еще у вас опечатка
Короче вот весь текст целиком : ![]()
Это сообщение отредактировал(а) volatile - 7.12.2012, 12:53 |
|||
|
||||
EvilsInterrupt |
|
||||
Executables research ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1019 Регистрация: 14.7.2007 Где: Железнодорожный, МО, Россия Репутация: 2 Всего: 9 |
volatile,
Ок, спасибо!
Потому что в реальной ситуации, а я сделал уменьшенный пример реальной ситуации, пользователь может воспользоваться функции нотификации об ошибках идущим по умолчанию с классом парсером. Но Может также задать и свою функцию. Мне же хочется передавать и внешне созданный функтор, т.к. копить ошибки куда удобнее. Если точнее сформулировать требования к этой ситуации, то нужно уметь передавать : 1) Как указатель на обычную функцию 2) Так и внешне созданный объект класса с переопределенным operator(), который позволит удобным способом накапливать ошибки Пока склоняюсь к шаблонному решению,на подобии того что сделано в std::for_each.
|
||||
|
|||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
EvilsInterrupt,
boost::function в комплекте с boost::bind сделают мечты реальностью )) для С++11 и буста не надо..все в коробке)) |
|||
|
||||
EvilsInterrupt |
|
|||
Executables research ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1019 Регистрация: 14.7.2007 Где: Железнодорожный, МО, Россия Репутация: 2 Всего: 9 |
mes,
Полностью согласен по поводу буста, в своих проектах(домашних) применяю его и по поводу новых технологий в виде С++11 тоже согласен, но не всегда можно применить все что душе хочется :( Попробую сформулировать проблему еще раз, а то кажется меня не понимают ;) Вообщем мне надо на обычном С++03 мою проблему решить, т.к. он MSVS 2008. На псевдокоде то что я хочу получить выглядит примерно так:
В существующем коде(моих тулзах) применяются иногда свои функции аналоги defErrorHandler, их переписать нет желания. Слишком много моих тулзов, которые я уже оттестировал и отладил может поломаться. Но в текущей тулзе, которую сейчас пишу, мне куда удобней написать класс функтор. Возникает вопрос: Как имея: 1) Обычные функции подобные defErrorHandler 2) Имея класс функтор Подавать в explicit-конструктор класса парсера как п.1 так и п.2 ? При этом текущие тулзы имеют семантику использования парсера в таком виде: Parser parser1(), т.е. обработчик по умолчанию. |
|||
|
||||
volatile |
|
||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 37 Всего: 85 |
EvilsInterrupt, а что запрещает буст::функшен использовать? там действительно все очень удобно.
Кроме-того у вас помимо основной проблемы, еще много "шума".
defErrorHandler - вовсе не обычная функция, это функция-мембер. а это 2 большие разницы. Кроме-того, у вас функтор, используется не в СТЛ-овском смысле. Он передается как ссылка на существующий "объект с состоянием", и не очень понятно, это требование, или просто побочный эффект.
Если обычная функция, это действительно обычная функция, а передача функтора в виде ссылки на существующий "объект с состоянием"- требование, то можно сделать так:
Читайте комменты в коде. (если бы не вышеизложенные требования, то можно было бы проще) Добавлено через 1 минуту и 9 секунд Если опять не то, то постарайтесь упростить код вопроса, убрав все лишнее. Как я уже говорил, у вас много лишнего "шума", причем не понятно, что из этого требование, а что случайный/ошибочный код. |
||||||
|
|||||||
volatile |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 37 Всего: 85 |
Да, и забыл привести вывод:
Если обычная функция, это не обычная функция ![]() |
|||
|
||||
EvilsInterrupt |
|
|||
Executables research ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1019 Регистрация: 14.7.2007 Где: Железнодорожный, МО, Россия Репутация: 2 Всего: 9 |
volatile,
Весь этот "огород" когда-то мне показался вполне логичным на мое желание дать возможность назначить функцию обработчика ошибки, т.к. обработчик предоставляемый по умолчанию приводил к бросанию исключений в случае обнаружения ошибок, что не во всех моих тулзах было нужно. Спасибо за внимание, ну и раз Вы уж упомянули "было бы проще". Хотелось бы Ваше проектное решение увидеть,если конечно не затруднит ) |
|||
|
||||
volatile |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 37 Всего: 85 |
EvilsInterrupt, ну это подошло или нет?
|
|||
|
||||
EvilsInterrupt |
|
|||
Executables research ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1019 Регистрация: 14.7.2007 Где: Железнодорожный, МО, Россия Репутация: 2 Всего: 9 |
volatile,
Да, Спасибо! Пока не вижу ничего чтобы сказать "не подходит". Все-таки хотелось бы увидеть решение более опытного товарища ;) |
|||
|
||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
вот скажите причем тут ехплицит ? зачем отвлекаться на несущественные детали ? Добавлено через 3 минуты и 13 секунд если готовое использовать не получается попробую показать ход мыслей, для решения подобных задач )) |
|||
|
||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
итак мы должны для одного и то же действия использовать полиморфизм, при этом, забегая вперед, имеются, как минимум, две возможности.. посредством виртуальных функций или "привязыванием", но для общего представления это не важно.. также, нам нужно это сделать, чтоб для пользователя было прозрачным.. значит нужен враппер, и так как враппер долже иметь состояние, значит используем функтор.. итого две подзадачи.. 1. адаптация функции/функтора 2. сокрытие под удобным интерфейсом |
|||
|
||||
mes |
|
||||||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
допустим интерфейс имеет такую структуру
тогда нам нужна пару адаптеров, один для функции другой для функтора..
для функтора аналогично.. Добавлено через 9 минут и 43 секунды теперь обернем интерфейс
|
||||||
|
|||||||
![]() ![]() ![]() |
Правила форума "С++:Общие вопросы" | |
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |