If I have a class 'Bar':
// bar.h
class Bar
{
public:
Bar() { }
};
that I forward declare to use with an std::unique_ptr in another class 'Foo':
// foo.h
#include <memory>
class Bar;
class Foo
{
public:
Foo();
private:
std::unique_ptr<Bar> bar_;
};
and whose definition I include in the implementation file of Foo:
// foo.cpp
#include "foo.h"
#include "bar.h"
Foo::Foo()
: bar_(new Bar)
{ }
I get the the compile-time error "Invalid application of 'sizeof' to an incomplete type 'Bar'".
I understand from here and here that to fix this, I can declare Foo's destructor in foo.h and move its empty definition to foo.cpp. What I don't understand is, why that fixes it. I read that std::unique_ptr sometimes requires to know the full definition of its type. It would make sense to me if I would have to include Bar from bar.h so that the unique_ptr sees its definition. But what does the destructor of Foo have to do with the visibility of Bar, and why does declaring ~Foo() in foo.h and defining it in foo.cpp silence the error?