Рассмотрим следующий фрагмент кода. Деструктор boost::scoped_ptr вызывается в конце основной функции. Деструктор использует boost::checked_delete для освобождения инкапсулированного указателя виджета.
#include <boost/scoped_ptr.hpp>
#include <iostream>
class Widget;
Widget *make_widget();
int main()
{
boost::scoped_ptr<Widget> sp(make_widget());
// std::cout << sizeof(Widget) << std::endl;
}
class Widget
{
public:
Widget() {}
~Widget() { std::cout << "Widget destructor called." << std::endl; }
};
Widget *make_widget()
{
return new Widget;
}
Я ожидал, что этот код не скомпилируется, поскольку класс Widget неполный в момент вызова деструктора scoped_ptr<Widget>
. Однако это чисто компилируется в g++ 4.8 и Visual Studio 2010. Обратите внимание на закомментированный оператор с выражением sizeof(Widget)
в основной функции. Если я раскомментирую его, он не сможет скомпилироваться, что означает, что Widget
должен быть неполным в этот момент.
Каково правильное объяснение такого поведения?
РЕДАКТИРОВАТЬ: некоторые ответы (теперь удаленные) указывали на поведение undefined, но я ожидал, что использование checked_delete в деструкторе scoped_ptr
вызовет сбой компиляции. FWIW, я использую Boost 1.55.
check_delete
поймает использование неполного типа, поэтому я очень удивлен этой компиляцией с комментариямиsizeof
. - person Matthieu M.   schedule 19.07.2014struct SP { ~SP() { depete ptr; } /* ... */ };
илиstruct SP { ~SP(); /* ... */ };
. Если деструктор не является встроенным, то его не нужно знать в момент вызова, поэтому типptr
также не нужен. - person Kerrek SB   schedule 19.07.2014