2

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?

AlexxanderX
  • 237
  • 1
  • 5
  • 25
  • Why don't you `#include` the headers for State, WConsole and WMessage in `Engine.hpp`? You redeclare (but do not define) the classes there. That's why you can't apply `sizeof` to them. – jogojapan Jan 05 '14 at 13:40
  • If I include all headers it's working, but I want to follow that style. I want to know the exactly reason why doesn't work because if we cut everything related to window::Console and window::Message and we only keep the code related to window::State the code above compile with no error. – AlexxanderX Jan 05 '14 at 13:46
  • Probably you don't declare any `unique_ptr`. And you don't do anything else that requires the data type to be fully defined. In any case, your use of unique-ptr means that `sizeof` is applied to certain data types, and for that, obviously, they need to be fully defined. How can the compiler determine the size of a data type without knowing its definition? – jogojapan Jan 05 '14 at 13:47
  • Yes I declare: std::vector< std::unique_ptr > m_windowObjects; – AlexxanderX Jan 05 '14 at 13:51
  • 1
    Well, a vector of unique-ptr is not the same as a unique-ptr. Have you looked at the link juanchopanza provided? Your vector declaration as well as how you use it in Engine.hpp may not require the full data type definition of `State`. If vector resizing, deallocation etc. happen somewhere else, it may well compile. – jogojapan Jan 05 '14 at 13:56

2 Answers2

3

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

Community
  • 1
  • 1
AlexxanderX
  • 237
  • 1
  • 5
  • 25
2

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.

Alan Stokes
  • 18,320
  • 3
  • 41
  • 63
  • If we cut everything related to window::Console and window::Message and we only keep the code related to window::State the code above compile with no error and still the window::State is not included in header. – AlexxanderX Jan 05 '14 at 13:42
  • 4
    Not quite: it can be incomplete, if some conditions are satisfied. See [here](http://stackoverflow.com/questions/6012157/is-stdunique-ptrt-required-to-know-the-full-definition-of-t). – juanchopanza Jan 05 '14 at 13:48
  • @juan Thanks, I didn't know that. – Alan Stokes Jan 05 '14 at 13:56
  • @juan Thanks for the link. Now I understood that I have somewhere an incomplete part for which unique_ptr need a complete one. My question is what to do: to include the headers or to change to shared_ptr? ( I don't access same resource from multiple pointers) – AlexxanderX Jan 05 '14 at 17:49
  • Personally I would just include the headers - minimising header dependencies is good, but not at the expense of distorting the semantics of the program (and increasing runtime overhead). – Alan Stokes Jan 05 '14 at 18:12