Недостатки передачи функций?

#c #class #function #mutable

#c #класс #функция #изменяемый #c

Вопрос:

Я изучаю C (исходя из Java) и недавно обнаружил, что вы можете передавать функции по кругу. Это действительно круто и, я думаю, чрезвычайно полезно. Теперь я думал о том, как я мог бы это использовать, и одной из идей, которая пришла мне в голову, был полностью настраиваемый класс.

Лучшим примером моего подхода к полностью настраиваемым классам (коду) был бы, скажем, класс person. У человека будут все функции, относящиеся к P. Позже человек может взять в руки меч (Ы), так что теперь у человека есть доступ ко всем функциям, относящимся как к P, так и S.

Существуют ли ограничения или проблемы с производительностью при этом? Это неаккуратно и просто не одобряется?

Любое понимание является образовательным, спасибо.

~Aedon

Комментарии:

1. FWIW: В Java моделируется то же самое с передачей объектов с заданным номинативным типом. Например, потоку может быть передана выполняемая «функция» (ну, экземпляр объекта, у которого есть только один метод «Run»). Такие языки, как C # и Scala, скрывают эту деталь (но все равно передают функции как сахар поверх объектов).

2. Однако в java вам приходится жестко кодировать определение в классе (ну, вы также могли бы модифицировать класс на лету, но вам пришлось бы перекомпилировать, прежде чем вы смогли бы использовать новый код, если я не ошибаюсь). Разве вы не можете просто передать функциональную переменную классу и выполнить функцию на c ? Без необходимости жесткого кодирования… Я думаю, тип?

3. Вы можете это сделать. Стоит ли это делать? почти всегда нет. Хитрость в том, чтобы знать, когда вы должны.

4. Не могли бы вы сообщить мне, почему? Просто дурной тон?

5. @AedonEtLIRA Определение класса должно быть жестко запрограммировано, так же, как и определение функции (исключая «волшебную» генерацию во время выполнения). В противном случае, оба обрабатываются как объекты (разных видов) и оба могут быть назначены.

Ответ №1:

При передаче функций — т.Е. указателей на функции на самом деле — вызовы всегда являются косвенными и, следовательно, возможно, медленнее, чем прямой вызов (и определенно медленнее, чем встроенный вызов в целом).

STL моделируется с помощью функторов. То есть: легкие функциональные объекты, у которых есть член operator(), который вызывается. Преимущество этого заключается в том, что он является весьма вероятным кандидатом для встраивания, особенно если функтор и operator() очень просты (как, например, std::less<T> ).

Смотрите также:http://www.sgi.com/tech/stl/functors.html

Ответ №2:

Наблюдается небольшое снижение производительности, поскольку указатель или ссылка должны быть разыменованы перед вызовом функции.

Это очень выгодная функция. Многие шаблоны проектирования и полиморфизм зависят от указателей на функции. Ознакомьтесь с «Шаблоном проектирования для посетителей».

Другое использование — для таблицы функций. Например, вы могли бы написать универсальный движок меню, который отображает разные меню с использованием разных функций.

Также изучите «Шаблон проектирования фабрики».

Ответ №3:

Нет абсолютно ничего плохого в передаче функции, но это своего рода примитивно и ограничивает. Часто у вас есть некоторые данные, которые вы хотите связать с функцией, в дополнение к параметрам, которые вы ей передаете. Также вы можете захотеть сгруппировать связанные функции вместе и передавать их как одно целое. Поздравляю, вы только что описали класс C !

Если вы хотите увидеть, как C действительно может размыть границы, рассмотрите функтор. Это класс, который имеет operator() метод, так что вы можете вызывать его точно так же, как вы бы вызывали функцию. У него есть два непосредственных преимущества перед обычной функцией: он может сохранять состояние между вызовами и может быть встроен компилятором для повышения производительности. Не редкость, когда std::sort , например, C qsort превосходит более старый, потому что qsort использует указатель на функцию, в то время как std::sort использует функтор.

Комментарии:

1. Спасибо, я посмотрю на функтор.