несоответствие документации boost :: scoped_ptr? - PullRequest
2 голосов
/ 25 октября 2011

boost::scoped_ptr документация содержит пример методики, называемой Идиома Ручка / Тело. Там это описывается следующими словами:

Пример программы scoped_ptr_example_test.cpp включает заголовочный файл, scoped_ptr_example.hpp, который использует scoped_ptr <> для неполного типа скрыть реализацию.

Однако в то же время в документации для checked_delete указано:

Особенно проблематичным является случай, когда деструктор умного указателя, такой как boost :: scoped_ptr :: ~ scoped_ptr, создается с неполным типом . Это часто может привести к молчанию, трудно отследить отказы. Предоставленные шаблоны функций и классов могут использоваться для предотвращения этих проблем, так как они требуется полный тип и в противном случае вызвать ошибку компиляции.

scoped_ptr действительно использует checked_delete в своей реализации. Мне кажется, что два отрывка противоречат друг другу. Кроме того, мне не удается скомпилировать мой код, который пытается использовать предложенный трюк, со следующим сообщением:

checked_delete.hpp:32: error: invalid application of 'sizeof' to 
incomplete type 'MyClass'

Так что, действительно, документация scoped_ptr ошибочна или я просто что-то пропустил?

Ответы [ 2 ]

5 голосов
/ 25 октября 2011

Они не противоречат друг другу. Поскольку scoped_ptr является шаблоном и поскольку в коде нет явного создания экземпляра, каждый метод создается по требованию. Это означает, что тип должен быть завершен к моменту создания экземпляра ~scoped_ptr<>, который в этом случае находится в файле .cpp после завершения удерживаемого типа (ищите example::~example(){} рядом с концом файла, который где ~scoped_ptr<> создается)

Это на самом деле интересный случай использования для деструктора, определенного пользователем, который выглядит точно так же, как сгенерированный компилятором, но позволяет вам контролировать , где / , когда происходит разрушение включить шаблон PIMPL с помощью некоторых интеллектуальных указателей. Если деструктор не был объявлен и определен, то деструктор будет неявно определен компилятором, где это необходимо, и тип будет неполным, что вызовет UB.

2 голосов
/ 25 октября 2011

Функция-член шаблона класса создается только там, где она есть используемый. Единственное место boost::scoped_ptr::~scoped_ptr используется в модулях деструктор example. Который определен в scoped_ptr_example.cpp, после определения example::implementation завершено. Функция boost::checked_delete разработан так, что он не будет компилироваться, если тип неполный; boost::scoped_ptr::~scoped_ptr использует это так, чтобы код не скомпилируется, если вы попытаетесь вызвать его в контексте, где тип не полный.

(FWIW: использование boost::scoped_ptr в идиоме pimpl немного излишне, и не очень полезно; так как вы должны предоставить пользовательский деструктор во всяком случае, это на самом деле не стоит много, и добавляет немного сложность.)

...