0

I have some classes that look like this:

World.h:

#ifndef WORLD_H_
#define WORLD_H_
#include "GameObject.h"
#include <vector>

class World
{
public:
std::vector<GameObject*> objects;

World();
virtual ~World();
void add(GameObject*);
void initialize();
void update();
void render();
};

#endif /* WORLD_H_ */

GameObject.h:

#ifndef GAMEOBJECT_H_
#define GAMEOBJECT_H_
#include "util/Point.h"
#include "World.h"

class GameObject
{
public:
World *world;
Point *position;
GameObject();
virtual ~GameObject();

virtual void update();
virtual void render();
};

#endif /* GAMEOBJECT_H_ */

Why does it give an error:
"World.h, line 9 - 'GameObject' has not been declared " and
"World.h, line 13 - 'GameObject' was not declared in this scope"?

I am using Linux GCC 4.8.1 compiler.

Jared Loomis
  • 65
  • 1
  • 3
  • 10

1 Answers1

3

You have a circular include dependency. But in this case, you can use forward declarations instead of includes:

#ifndef WORLD_H_
#define WORLD_H_
#include <vector>

class GameObject; // forward declaration

class World
{
  // as before
};
#endif

and

#ifndef GAMEOBJECT_H_
#define GAMEOBJECT_H_

class World;
class Point;

class GameObject
{
  // as before
};
#endif

Then, include the headers in the implementation files that need them.

For more details, see When to use forward declarations.

Community
  • 1
  • 1
juanchopanza
  • 223,364
  • 34
  • 402
  • 480
  • Actually I am wondering if it wouldn't make sense to include each file in the class. This way if you only need one of them in the implementation you don't have to include both. Isn't it part of the point of `#ifdef`s ? N.B: This is a question I am not affirming anything. – charly Aug 19 '13 at 19:16
  • @charly I don't know what it means to include a file in a class. And the point of the include guards is to avoid including the same thing more than once. – juanchopanza Aug 19 '13 at 19:18
  • Sorry I meant include the h file in the each other. i.e: add '#include "world.h"` in gameobject.h and `#include "gameobject.h"` in world.h. The guards will ensure that it is defined only once and if you only need GameObject you will just include gameobject.h not both gameobject.h and world.h. Will this cause a problem? – charly Aug 19 '13 at 19:22
  • When I do this it has an error saying "forward declaration of class Point" – Jared Loomis Aug 19 '13 at 19:29
  • @JaredLoomis if that is so, then you must have different code to what you have shown. Have a look at the link at the end of my answer, that explains when you can use forward declarations. You only need to remove *one* of the includes to break the cyclic dependency, but from your code it looked like you could remove both. – juanchopanza Aug 19 '13 at 19:31
  • @juanchopanza - yes, I declared world as a World instead of World*, I fixed it, but it still has another error "forward declaration of class Point" – Jared Loomis Aug 19 '13 at 19:32
  • @charly: That's exactly the problem in the question. Each header tries to include the other, but the result (thanks to the guards) is that one is included before the other, so the first to be included can't see the declarations in the second. – Mike Seymour Aug 19 '13 at 19:34
  • Sorry, I was leaving includes out. this answer solves the problem completely. Thank you. – Jared Loomis Aug 19 '13 at 19:35