I am failing to understand the following scenario. It is about using the pimpl idiom based on the std::unique_ptr
in a derived class. Given a simple class hierarchy declared as follows:
class Foo
{
public:
virtual ~Foo();
//...
};
struct X;
class Bar : public Foo
{
public:
~Bar();
//...
private:
std::unique_ptr<X> _d;
};
I am showing only code relevant for my question.
Imagine class Foo
being some interface and the class 'Bar' which implements it. I want to use the pimpl idiom in Bar
. Destructors are virtual and defined in the corresponding cpp files. Also the full definition of the struct X
, which is only forward declared, is accessible in the cpp, so that for the destructor of Bar
destructor std::unique_ptr<X>::~unique_ptr()
can be instantiated. When I try to create an instance of Bar
, I would expect it to work
int main()
{
Bar b;
}
Instead, I get the compilation error use of undefined type 'X' followed by the message can't delete an incomplete type (in Visual Studio 2013 Update 2). However, if I explicitly add the default constructor to Bar
, main()
compiles/builds correctly.
class Foo
{
public:
virtual ~Foo();
};
struct X;
class Bar : public Foo
{
public:
Bar();
~Bar();
private:
std::unique_ptr<X> _d;
};
I am failing to see the correspondence between the presence of default constructors in this class hierarchy and the completeness of the struct X
in the context of the std::unique_ptr<X>
in Bar
. Could someone explain or point to a possibly already existing explanation?