Подтвердить что ты не робот

Тип дебетора в unique_ptr vs. shared_ptr

Я подумал, что очень любопытно, когда я обнаружил, что стандарт определяет std::unique_ptr и std::shared_ptr двумя совершенно разными способами относительно Deleter, которыми может владеть указатель. Вот объявление из cppreference:: unique_ptr и cppreference:: shared_ptr:

template<
    class T,
    class Deleter = std::default_delete<T>
> class unique_ptr;

template< class T > class shared_ptr;

Как вы видите, unique_ptr "сохраняет" тип объекта Deleter в качестве аргумента шаблона. Это также можно увидеть в способе удаления Deleter из указателя позже:

// unique_ptr has a member function to retrieve the Deleter
template<
    class T,
    class Deleter = std::default_delete<T>
>
Deleter& unique_ptr<T, Deleter>::get_deleter();

// For shared_ptr this is not a member function
template<class Deleter, class T>
Deleter* get_deleter(const std::shared_ptr<T>& p);

Может кто-нибудь объяснить рациональность этой разницы? Я явно одобряю концепцию unique_ptr, почему это не относится к shared_ptr? Кроме того, почему get_deleter была бы не-членной функцией в последнем случае?

4b9b3361

Ответ 1

Здесь вы можете найти оригинальное предложение для интеллектуальных указателей: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1450.html

Он точно отвечает на ваш вопрос:

Поскольку делетер не является частью типа, изменение стратегии распределения не нарушает совместимость с исходным кодом или двоичным кодом и не требует перекомпиляции клиента.

Это также полезно, поскольку дает клиентам std::shared_ptr некоторую дополнительную гибкость, например, экземпляры shared_ptr с разными удалениями могут храниться в одном контейнере.

Кроме того, поскольку реализация shared_ptr нуждается в блоке разделяемой памяти так или иначе (для хранения счетчика ссылок), и потому, что alreay должен быть накладными расходами по сравнению с необработанными указателями, добавление удаляемого типа удаления не является большим сделка здесь.

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