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?