fateflame
fateflame

Reputation: 157

Use unique_ptr<T> with forward declearation leads to C2027 and C2338

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?

Upvotes: 2

Views: 305

Answers (1)

John Zwinck
John Zwinck

Reputation: 249133

You need to define the constructor in the .cpp file, not just the destructor.

If the Outer constructor fails, it will need to destroy m_ptr, that that requires knowing the definition of class Inner.

Upvotes: 2

Related Questions