Должен ли я прекратить использование абстрактных базовых классов / интерфейсов и вместо этого использовать boost :: function / std :: function? - PullRequest
12 голосов
/ 07 марта 2012

Я только что узнал о том, что такое std :: function и для чего он используется, и у меня возник вопрос: теперь, когда у нас есть делегаты, где и когда мы должны использовать абстрактные базовые классы, и когда вместо этого,мы должны реализовать полиморфизм через объекты std :: function, передаваемые в общий класс?Получил ли ABC смертельный удар в C ++ 11?

Лично я до сих пор сталкивался с тем, что переключение делегатов намного проще для кода, чем создание нескольких унаследованных классов для каждого конкретного поведения ... поэтому я немного запуталсяо том, насколько полезными будут абстрактные основы с этого момента.

Ответы [ 2 ]

19 голосов
/ 07 марта 2012

Предпочитают четко определенные интерфейсы, а не обратные вызовы

Проблема с 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 ++.

1 голос
/ 07 марта 2012

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

Класс, инкапсулирующий методы и данные, которые к нему относятся.

Указатель на функцию, это указатель на функцию.У него нет понятия инкапсулирующего объекта, он просто знает о параметрах, переданных ему.

Когда мы пишем классы, мы описываем четко определенные объекты.

Указатели на функции отлично подходят длямного вещей, но изменение поведения объекта не обязательно является целевой аудиторией (хотя я допускаю, что могут быть ситуации, когда вы захотите это сделать, например, обратные вызовы, как упоминает Doug.T).

Пожалуйста, не путайте их.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...