Here is a simple version of code:
//Outer.h
class Inner;
class Outer
{
std::unique_ptr<Inner> m_ptr;
public:
~Outer();
}
//----------------------------------------
//Outer.cpp
#include "Outer.h"
#include "Inner.h" //here is the full definition of class Inner
Outer::~Outer(){};
//----------------------------------------
//main.cpp
#include "Outer.h"
int main()
{
Outer b;
return 0;
}
When I compile "main.cpp", the compiler returns with C2338(can't delete an incomplete type) and C2027(use of undefined type 'Inner')
I have read Is std::unique_ptr required to know the full definition of T? and I know if I include "Inner.h" in "main.cpp", the problem can be solved. But why?
For a raw pointer, I can simply use forward declearation in header file(Outer.h
), include implementation(Inner.h
) in cpp file(Outer.cpp
), delete it manully in destructor, and no need to include implementation again whevever I use it.
But for a unique_ptr, similarly I use forward declearation in header file(Outer.h
), include implementation(Inner.h
) in cpp file(Outer.cpp
), delete it automatically in destructor(with default destructor), But why do I need to include inner class's implementation(Inner.h
) again when I use it?
Bag::~Bag()
will callstd::unique_ptr<goods>::~unique_ptr
, which requiresgoods
to be a complete type as it might callgoods::~goods()
(even though it doesn't actually call it as the pointer isnullptr
, it is still required by the standard. With raw pointers you still have to construct and destruct at the memory pointed to). This is in the table provided by the answer to that question: stackoverflow.com/a/6089065/5754656: The destructor forstd::unique_ptr<T>
requires a complete definition forT
. – Artyer