I have found it useful to use forward declaration of classes in combination with std::unique_ptr as in the code below. It compiles and works with GCC, but the whole thing seem kind of strange, and I wonder if this is standard behaviour (i.e., required by the standard)? Since B isn’t a complete type when I declare the unique_ptr.
A.hpp
#include <memory>
class B;
class A {
std::unique_ptr<B> myptr;
// B::~B() can't be seen from here
public:
~A();
};
A.cpp
#include "B.hpp"
//B.hpp has to be included, otherwise it doesn't work.
A::~A() = default; // without this line, it won't compile
// however, any destructor definition will do.
I suspect this has to do with the destructor (and therefore the need to call the destructor of unique_ptr<B>) is defined in a specific compilation unit (A.cpp).
It’s explicitly legal. The rule is that the types used to instantiate
a template in the standard library must be complete, unless otherwise
specified. In the case of
unique_ptr, §20.7.1/5 says “[…] Thetemplate parameter T of unique_ptr may be an incomplete type.”
There are certain operations on the pointer which require a complete
type; in particular, when the object will actually be destructed (at
least with the default deleter). In your example, for example, if
A::~A()were inline, this might cause problems. (Note that if youdon’t declare the destructor yourself, it will be inline. Which
partially defeats the purpose of using
std::unique_ptr.)