Filipe Sousa wrote:
Hi!
I'm having trouble implementing Pimpl idiom with Qt. Look at the following code:
class IndispFilterWidget : public QHBox { Q_OBJECT public: IndispFilterWidget(QWidget* parent = 0);
private: struct Private; boost::scoped_ptr<Private> d; };
struct IndispFilterWidget::Private { QIntDict<BrushButton> buttons; };
IndispFilterWidget::IndispFilterWidget(QWidget* parent) : QHBox(parent) , d(new Private) { }
and see the error:
/usr/include/boost/checked_delete.hpp: In function 'void boost::checked_delete(T*) [with T = exames::calendario::IndispFilterWidget::Private]': /usr/include/boost/scoped_ptr.hpp:77: instantiated from 'boost::scoped_ptr<T>::~scoped_ptr() [with T = exames::calendario::IndispFilterWidget::Private]' /home/fsousa/projects/GAL/BUILD/modules/exames/calendario/../../../../modules/exames/calendario/IndispFilterWidget.h:31: instantiated from here /usr/include/boost/checked_delete.hpp:32: error: invalid application of 'sizeof' to incomplete type 'exames::calendario::IndispFilterWidget::Private' /usr/include/boost/checked_delete.hpp:32: error: creating array with size zero ('-0x000000001') /usr/include/boost/checked_delete.hpp:33: error: invalid application of 'sizeof' to incomplete type 'exames::calendario::IndispFilterWidget::Private' /usr/include/boost/checked_delete.hpp:33: error: creating array with size zero ('-0x000000001') /usr/include/boost/checked_delete.hpp:34: warning: possible problem detected in invocation of delete operator: /usr/include/boost/checked_delete.hpp:29: warning: 'x' has incomplete type /home/fsousa/projects/GAL/BUILD/modules/exames/calendario/../../../../modules/exames/calendario/IndispFilterWidget.h:45: warning: forward declaration of 'struct exames::calendario::IndispFilterWidget::Private'
If I remove Q_OBJECT macro or add a destructor the code compiles fine. I don't have a problem with shared_ptr, only with scoped_ptr.
scoped_ptr cannot be used with incomplete types, unfortunately, and thus is not available for use in the pimpl idiom. You can: 1. Use shared_ptr. 2. Use a regular pointer and delete it in the class destructor (in the implementation file). 3. Not much else you can do. Write your own incomplete_scoped_ptr, maybe. :o)