Предпочитают четко определенные интерфейсы, а не обратные вызовы
Проблема с std::function
(ранее boost::function
) заключается в том, что большую часть времени вам требуется обратный вызов метода класса и, следовательно, необходимо привязать this
к объекту функции. Однако в коде вызова у вас нет возможности узнать, все еще ли рядом this
. На самом деле, вы даже не представляете, что существует даже this
, потому что bind преобразовал сигнатуру вызывающей функции в то, что требует вызывающая сторона.
Это может естественным образом вызывать странные сбои, когда обратный вызов пытается запустить методы для классов, которых больше не существует.
Конечно, вы можете использовать shared_from_this
и привязать shared_ptr к обратному вызову, но тогда ваш экземпляр может никогда не исчезнуть. Человек, которому вы перезвонили, теперь участвует в вашей собственности, даже не зная об этом. Вы, вероятно, хотите более предсказуемое владение и разрушение.
Другая проблема, даже если вы можете заставить обратный вызов работать нормально, связана с обратными вызовами, код может быть слишком 1017 * слишком отсоединен . Отношения между объектами могут быть настолько сложными, чтобы установить, что читаемость кода снижается. Интерфейсы, однако, обеспечивают хороший компромисс между соответствующим уровнем развязки с четко определенными отношениями, как это определено контрактом интерфейса. Вы также можете более четко указать в этих отношениях такие вопросы, как, кому кому принадлежит, порядок уничтожения и т. Д.
Дополнительная проблема с std::function
заключается в том, что многие отладчики не поддерживают их должным образом. В VS2008 и функциях повышения вы должны пройти около 7 слоев, чтобы добраться до своей функции. Даже если при прочих равных условиях лучшим вариантом был обратный вызов, явного раздражения и потраченного времени на случайное превышение цели std::function
является достаточной причиной, чтобы этого избежать. Наследование является основной особенностью языка, и переход в переопределенный метод интерфейса происходит мгновенно.
Наконец, я просто добавлю , у нас нет делегатов в C ++ . Делегаты в C # являются основной частью языка, так же как наследование в C ++ и C #. У нас есть функция библиотеки std, в которой IMO - это один слой, удаленный от основных функций языка. Таким образом, он не будет тесно связан с другими основными функциями языка. Вместо этого он помогает формализовать представление о функциональных объектах, которые долгое время были идиомой C ++.