Reputation: 276
I have next classes:
State.hpp
...
class Engine;
namespace window
{
class State
{ ... } }
WConsole.hpp
...
class Engine;
namespace window
{
class Console: public State
{ .. } }
WMesssage.hpp
...
class Engine;
namespace window
{
class Message: public State
{ ... } }
And all classes link to Engine class:
Engine.hpp
...
namespace window
{
class State;
class Console;
class Message;
}
class Engine
{
...
std::vector< std::unique_ptr<window::State> > m_windowObjects;
std::unique_ptr<window::Console> m_consoleWindow;
std::unique_ptr<window::Message> m_messageWindow;
...
}
And in Engine.cpp I include the headers:
#include "Engine.hpp"
#include "WState.hpp"
#include "WConsole.hpp"
#include "WMessage.hpp"
If I try to compile I get this errors:
In file included from /usr/include/c++/4.8.2/memory:81:0,
from /usr/local/include/SFGUI/Signal.hpp:6,
from /usr/local/include/SFGUI/Object.hpp:4,
from /usr/local/include/SFGUI/Widget.hpp:4,
from /usr/local/include/SFGUI/Container.hpp:4,
from /usr/local/include/SFGUI/Bin.hpp:4,
from /usr/local/include/SFGUI/SFGUI.hpp:6,
from ./include/Handler.hpp:4,
from main.cpp:1:
/usr/include/c++/4.8.2/bits/unique_ptr.h: In instantiation of 'void std::default_delete<_Tp>::operator()(_Tp*) const [with _Tp = window::Console]':
/usr/include/c++/4.8.2/bits/unique_ptr.h:184:16: required from 'std::unique_ptr<_Tp, _Dp>::~unique_ptr() [with _Tp = window::Console; _Dp = std::default_delete<window::Console>]'
./include/Engine.hpp:21:7: required from here
/usr/include/c++/4.8.2/bits/unique_ptr.h:65:22: error: invalid application of 'sizeof' to incomplete type 'window::Console'
static_assert(sizeof(_Tp)>0,
^
/usr/include/c++/4.8.2/bits/unique_ptr.h: In instantiation of 'void std::default_delete<_Tp>::operator()(_Tp*) const [with _Tp = window::Message]':
/usr/include/c++/4.8.2/bits/unique_ptr.h:184:16: required from 'std::unique_ptr<_Tp, _Dp>::~unique_ptr() [with _Tp = window::Message; _Dp = std::default_delete<window::Message>]'
./include/Engine.hpp:21:7: required from here
/usr/include/c++/4.8.2/bits/unique_ptr.h:65:22: error: invalid application of 'sizeof' to incomplete type 'window::Message'
From what I see I don't get an error relating to window::State so mean that I introduced it in the right way, but why I get error relating to window::Console and window::Message? May affect that classes window::Console and window::Message are derivated from window::State?
Upvotes: 3
Views: 20869
Reputation: 41
Short answer:
Long answer:
Imagine the following:
//B.h
class A;
class B
{
std::unique_ptr<A> m_A;
public:
B();
};
//B.cpp
#include "B.h"
#include "A.h"
B::B()
: m_A(new A())
{
}
lets see B.i result file after executing the following command (g++ -std=c++11 B.cpp -E B.i):
class A;
class B
{
std::unique_ptr<A> m_A;
public:
B();
};
# 2 "B.cpp" 2
# 1 "A.h" 1
class A
{
public:
int mInt;
explicit A( int aInt = 0 )
: mInt(aInt)
{
}
};
# 3 "B.cpp" 2
B::B()
: m_A(new A())
{
}
Now comes the compiler part. According to cpp reference
If no user-declared prospective (since C++20)destructor is provided for a class type (struct, class, or union), the compiler will always declare a destructor as an inline public member of its class.
lets imagine the file with a declared destructor ( of course there will be declared copy constructor, assignment operator, but lets stick with destructor only )
class A;
class B
{
std::unique_ptr<A> m_A;
public:
B();
~B(){} // <-------- FOCUS HERE
};
# 2 "B.cpp" 2
# 1 "A.h" 1
class A
{
public:
int mInt;
explicit A( int aInt = 0 )
: mInt(aInt)
{
}
};
# 3 "B.cpp" 2
B::B()
: m_A(new A())
{
}
Upvotes: 2
Reputation: 276
I modified to shared_ptr, but including the headers are still a option.
Here is the link for someone who may have same error here
Upvotes: 4
Reputation: 18964
The type argument to unique_ptr
must be a complete type for a lot of use cases (see comments for the details); a forward declared class is incomplete. You must have a full definition of the class visible.
Upvotes: 2