![]() |
|
Модераторы: Daevaorn |
![]()
|
|
| Merlin_ua |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 44 Регистрация: 22.11.2006 Репутация: нет Всего: нет |
Пример:
Пример сильно упрощен. Суть - реализовать динамическую подмену метода. Нужно в зависимости от значения, передаваемого в конструкторе, присоить f1 указатель на одну из функцию-метод этого же класса. Естественно код не работает. Как решить подобную задачу? |
|||
|
||||
| Lukkoye |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 86 Регистрация: 23.3.2013 Репутация: 1 Всего: 1 |
http://rextester.com/KGK12631
Так же рекомендую ознакомиться: http://forum.vingrad.ru/forum/topic-378684.html Это сообщение отредактировал(а) Lukkoye - 13.8.2014, 23:29 |
|||
|
||||
| Cheloveck |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1578 Регистрация: 26.7.2008 Где: Тула Репутация: 3 Всего: 32 |
Можно юзать паттарн strategy, если не пугает небольшой оверхед с использованием виртуальных вызовов.
Ещё есть кашерный способ с использованием шаблонных функторов. Правда, не всегда можно использовать.
-------------------- ![]() |
|||
|
||||
| Lukkoye |
|
||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 86 Регистрация: 23.3.2013 Репутация: 1 Всего: 1 |
Ваш способ не кошерный по ряду причин: 1. Нет ни какой необходимости увеличивать размер объекта ---> мембер не нужен. 2. Оверхед ---> агрегат запускает функцию, которая запускает функцию мембера ---> это избыточный оверхед в данном случае. 3. функция мембера никак не связанна с данными агрегата ---> должна быть const ---> можно заменить на свободную функцию. итого, вот вам более эффективная модель, лишенная этих досадных недостатков: http://rextester.com/KYRE18162
По аналогичной схеме можно работать и с нестатическими функциями-членами классов. Смысл идеи: передавать функцию, которую нужно запускать через параметр шаблона, а не через аргументы функций, или мемберы классов. Передаваемые через параметр шаблона функции 100% inline без каких бы то ни было штрафов, и оверхеда в рантайме. Это сообщение отредактировал(а) Lukkoye - 14.8.2014, 23:56 |
||||
|
|||||
| Cheloveck |
|
||||||||||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1578 Регистрация: 26.7.2008 Где: Тула Репутация: 3 Всего: 32 |
Это 1 байт против Ваших 8-ми (на 64-разрядных машинах): http://codepad.org/lj2HBuRV
Смотрим на асм, который выдаёт g++ и не наблюдаем оверхеда
А всё потому, что всё волшебным способом заинлайнилось.
Не совсем понятно предложение. Но исходя из вышеперечисленных соображения и возможность оборачивать свободные функции в структуры макросом, не считаю этот пункт хоть сколько-нибудь значащим. И да
http://ideone.com/Pn1xQ2 Это сообщение отредактировал(а) Cheloveck - 15.8.2014, 00:50 -------------------- ![]() |
||||||||||
|
|||||||||||
| Lukkoye |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 86 Регистрация: 23.3.2013 Репутация: 1 Всего: 1 |
Который можно было бы и не тратить совершенно зазря и на пустом месте. Против каких моих 8ми? В моем примере вообще нет мемберов. inline это конечно хорошо, только не факт в вашем случае. в случае с параметром шаблона - факт. boost::function/boost::bind с вами не согласны. Было время, я рассматривал различные варианты реализаций делегатов на плюсах (с++03). И собственный велосипед так же имеется. Я провел ряд сравнительных тестов. Все аналоги уступали бустовскому делегату. Не сказать, что сильно, но все таки велосипеды его не догоняли. В бустовском делегате не использовались аргументы функций, для передачи и сохранения объекта указателя на функцию-член, то есть там не делалось динамической связки. Вместо этого делалась статическая связка, путем передачи указатель на функцию-член через параметр шаблона. Что и делало его столь быстрым в работе. Ваше "и да" ---> std::function итак уже является тонкой оберткой над функторами. Высоко технологичное, черезвычайно быстрое средство запуска удаленных функций. Факт его использования делает ненужной вашу собственную обертку в принципе. Она получается избыточным велосипедом с квадратными колесами. Другое дело сам std::function. Вы можете нацеливать его куда угодно - на любые функции, и методы, с любыми именами,с различным количеством заранее прибинденных аргументов, бла бла бла. Ваша обертка в этом смысле прибита гвоздями к operator() с определенной сигнатурой. Теперь попробуйте нарисовать модель, которую подобно std::function можно нацеливать на самые разные функции, и биндить аргументы. Только имейте ввиду - если для классов, вы будете отдельно сохранять объект, и отдельно указатель на функцию-член, и делать динамическую связку - вы просадите рантайм, и ваш велосипед никогда по скорости не догонет std::function/std::bind. Это сообщение отредактировал(а) Lukkoye - 15.8.2014, 01:20 |
|||
|
||||
![]()
|
| Правила форума "С++:Общие вопросы" | |
|
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |