TL; DR Объявите явный деструктор и внедрите его в модуль кода (не в заголовочный файл).
Если вы не создадитедеструктор, затем компилятор создает пустой автоматический деструктор в каждом модуле перевода, который пытается уничтожить объект этого класса.Вы бы получили эквивалентное поведение, если бы вы определили пустой встроенный деструктор в заголовке класса.
Это вызывает ошибку, потому что деструктор также отвечает за вызов деструкторов всех полей класса, которые - по порядку - нужнысоздание шаблона метода boost::scoped_ptr<impl>::~scoped_ptr();
.Этот шаблон, в свою очередь, не может быть создан тогда, потому что он пытается удалить объект типа impl
, который только объявлен в этой области только вперед (и вам нужно полное определение, чтобы знать, как удалить этот объект.
OTOH, если вы объявляете не встроенный конструктор в заголовке, его код генерируется только в pimpl_sample.cpp
, где также содержится определение impl
, поэтому деструктор scoped_ptr может быть успешно создан.
Другие единицы перевода затем вызывают только деструктор pimpl_sample
как внешний метод, поэтому им не нужно генерировать его и создавать экземпляр деструктора scoped_ptr
самостоятельно.