0

So, i started learning C++ about a year ago, i learned Java C# and VB.NET before it. As it is now, i would consider myself a advanced C++ coder. However, theres one thing i dont quite get. The linking process. And heres the problem. Right now, im coding a XNA-like library for Game development, with a basic Component System - but i get Compiler errors when building it, C++ pretending it doesnt know a specific type, in this case, the GameComponent class doesnt know the ComponentSelector class (and vice versa), although its correctly included and typed. Im gonna show you my two header files, hopefully you can help me out.

ComponentSelector.hpp:

#ifndef COMPONENTSELECTOR_HPP
#define COMPONENTSELECTOR_HPP
#include<sem/System/Types.hpp>
#include<sem/System/GameComponent.hpp>
#include<vector>
namespace sem
{
    class ComponentSelector
    {
    public:
        GameComponent* getComponent1(); //GameComponent does not name a type
        GameComponent* getComponent2(); //GameComponent does not name a type
        GameComponent* getComponent3(); //GameComponent does not name a type
        void addComponent(GameComponent* item); //GameComponent does not name a type
        void removeComponent1();
        void removeComponent2();
        void removeComponent3();
        void clearList();
    private:
        std::vector<GameComponent*> m_Components;
    protected:
    };
}
#endif // COMPONENTSELECTOR_HPP

GameComponent.hpp:

#ifndef GAMECOMPONENT_HPP
#define GAMECOMPONENT_HPP

#include<sem/System/ComponentSelector.hpp>
#include <sem/System/Types.hpp>

namespace sem
{
    class GameComponent
    {
    public:
        virtual void load() = 0;
        virtual void unload() = 0;
        virtual void update() = 0;
        virtual void draw() = 0;

        ComponentSelector* m_Selector; //ComponentSelector does not name a type

        SEMlong getID();
        SEMstring getName();
        SEMstring getType();
    private:
        SEMlong m_ComponentID;
        SEMstring m_ComponentName;
        SEMstring m_ComponentType;
    protected:
    };
}

#endif // GAMECOMPONENT_HPP

Any solution and tips would be greatly appreciated.

tubberd
  • 540
  • 5
  • 15
  • 1
    After your first set of #includes, you should type Class GameComponent. This is called forward declaration. Then you can have the implementation come later, which is what you are doing. – Cory Kramer Feb 20 '14 at 19:06
  • You seem to indicate there are two header files here, but your question layout looks like just one. Are these in separate files or just one? If they are separate please update the question to reflect this. – Mike Webb Feb 20 '14 at 19:07
  • thanks. i updated it. – tubberd Feb 20 '14 at 19:12
  • Looks like an infinite recursion to me. GameComponent.hpp includes ComponentSelector.hpp which includes GameComponent.hpp which includes ComponentSelector.hpp, ad nauseam... – PaulMcKenzie Feb 20 '14 at 19:35
  • @PaulMcKenzie Thank's to the correctly placed _include-guards_ it won't recurse! – πάντα ῥεῖ Feb 20 '14 at 19:54

1 Answers1

1

You need a forward declaration for class ComponentSelector in your GameComponent class declaration:

// Remove this: #include<sem/System/ComponentSelector.hpp> 
#include <sem/System/Types.hpp>

namespace sem
{
    class ComponentSelector; // Note the forward declaration added!

    class GameComponent
    {
         // ...
         ComponentSelector* m_Selector; // Compiles now!
         // ...

I'd recommend to do the same in the ComponentSelector declaration header vice versa. Include the full class declarations then, where you are going to use any members (this is in the compilation units i.e. .cpp-files usually).

πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
  • if i do that, they compiler will fail when building and put out this error message (the old error is gone) : `||=== Build: x64 in sem (compiler: TDM GCC x64) ===| include\sem\System\Thread.hpp|21|warning: inline function 'static void sem::Thread::sleep(sem::SEMlong)' used but never defined [enabled by default]| include\sem\System\ComponentSelector.hpp.gch||No such file or directory| ||=== Build failed: 1 error(s), 1 warning(s) (0 minute(s), 3 second(s)) ===| ` – tubberd Feb 20 '14 at 19:40
  • @DanielWanner Read my updates, and lookup what forward declarations are meant for. Those errors you're mentioning are caused elsewhere. That one you've been asking for should be fixed if you follow my advice. – πάντα ῥεῖ Feb 20 '14 at 19:43
  • i know about the Thread::sleep warning, but the second error only occurs if i forward declarate the classes. – tubberd Feb 20 '14 at 19:47
  • i accidentially enabled compiling the "ComponentSelector.hpp" file. my fault. – tubberd Feb 20 '14 at 19:52
  • @DanielWanner Sorry, **no**! For _'static void sem::Thread::sleep(sem::SEMlong)'_ I can't tell from what you're giving from your sample. That seems to be another SO question, but don't forget to mention all the relevant code. – πάντα ῥεῖ Feb 20 '14 at 19:52
  • I got one problem left. im now doing forward declarations only in the headers, to avoid headaches like this one, and implementing the class in the .cpp file, which is where i include the header files aswell. of course, this way i cant access their members or anything like that. is there any workaround for this? i dont want to include other headers in header files, if possible – tubberd Feb 24 '14 at 21:16
  • @DanielWanner And what's the _problem left_ then? – πάντα ῥεῖ Feb 24 '14 at 21:18
  • @DanielWanner Sounds a reasonable design for me, while may not be necessary or possible (this **always** requires pointers or refernces for member variable definitions, as long you don't want to follow the [pimpl idion](http://stackoverflow.com/questions/60570/why-should-the-pimpl-idiom-be-used)) for every case you meet. Don't use the [Golden Hammer](http://en.wikipedia.org/wiki/Golden_hammer) anti-pattern please! – πάντα ῥεῖ Feb 24 '14 at 21:33