0

Im having a little problem with classes. Here is some of my code:

//GameMap.h
#ifndef GAMEMAP_H
#define GAMEMAP_H
#include "apath.h"

class GameMap
{
    /*class definition here*/
};

#endif

and

//apath.h
#ifndef APATH_H
#define APATH_H

class path
{
    //some code...
    void DoSomething(GameMap map);
    //rest of class body
};

#endif

I cant use GameMap in apath.h, when I try to include "GameMap.h in this file I get some stupid errors... I also tried to add class GameMap; before definition of path class. Nothing helped... I really need to use it here... If needed I can post some more code.

Thanx for any replies!

noisy cat
  • 2,563
  • 4
  • 28
  • 50
  • How do you compile your code? – Yet Another Geek Feb 05 '12 at 17:54
  • Okay so you are using class path in GameMap and GameMap in path? – Ahmed Masud Feb 05 '12 at 17:55
  • Can `void DoSomething(GameMap map);` be `void DoSomething(GameMap& map);`? – Pubby Feb 05 '12 at 17:55
  • Also, post your errors and the use of `path` in `GameMap` – Pubby Feb 05 '12 at 17:55
  • what you mean? I use dev c++, so mingw. If you mean about files, I have GameMap included from main, and apath from GameMap. – noisy cat Feb 05 '12 at 17:56
  • How do you expect apath.h to know about GameMap class? In gamemap.h, you have the class definition for GameMap *after* you include apath.h...like @YetAnotherGeek said, how do you compile your code? – mmtauqir Feb 05 '12 at 17:57
  • @Pubby Compiler says that GameMap is not defined, and its quite normal, becouse it wont be included 2nd time. I did something (dont know what exacly) and I got error in GameMap class, saying that a semi-colon is missing and one of the class methods is used somewhere else (im sure it isnt)... – noisy cat Feb 05 '12 at 18:01

5 Answers5

4

You should use forward declaration of class GameMap in apath.h:

class GameMap; // forward declaration

class path
{
    //some code...
    void DoSomething(GameMap map);
    //rest of class body
};    

Check: When can I use a forward declaration?

In following example I use forward declaration of class A so that I'm able to declare function useA that uses it:

// file a.h
class A;
void useA(A a);

and then in main.cpp I have:

#include "a.h"

class A
{
public:
    void foo() { cout << "A"; }
};

void useA(A a)
{
    a.foo();
}

which is absolutely correct, since class A is already defined here.

Hope this helps.

Community
  • 1
  • 1
LihO
  • 37,789
  • 9
  • 89
  • 156
2

You should check PIMPL idiom.

In path header:

class GameMap;

class Path
{
public:
  void useMap( GameMap * map );
};

In path source:

#include "Path.h"
#include "GameMap.h"

void Path::useMap( GameMap * map )
{
  // Use map class
}

More links: link and connected topic.

Community
  • 1
  • 1
Naszta
  • 7,104
  • 2
  • 30
  • 48
1

make external declaration in apath.h

class GameMap;

After it change signature of method:

void DoSomething(GameMap& map);

Or

void DoSomething(GameMap* map);
Dewfy
  • 21,895
  • 12
  • 66
  • 114
  • way 1 wouldn't work due to circular dependency. Also I think `DoSomething(GameMap map)` is equivalent with `DoSomething(const GameMap& map)` (added const) – Lol4t0 Feb 05 '12 at 17:59
1

You have a circular include problem. GamePath.h includes apath.h, so trying to include GamePath.h in apath.h is brittle at best and gives errors (your case) at worst. The best bet is to find which pieces of apath.h are used by GamePath.h, and refactor those into a common header file, say common.h, and include common.h in both GamePath.h and apath.h. That way you don't have a circular include anymore, and you can draw a graph of includes as a nice beautiful DAG.

Adam Mihalcin
  • 13,346
  • 3
  • 29
  • 49
1

You're trying to do circular includes, which are obviously forbidden.

I'd suggest you forward declare GameMap in apath.h and pass it as a const reference:

class GameMap; // forward declaration

class path
{
    //some code...
    void DoSomething(const GameMap &map);
    //rest of class body
};

const ref is better than simple ref since it tells explicitly that the object cannot change during the function call.

amyrit
  • 437
  • 4
  • 7