I've got two classes, Entity and Level. Both need to access methods of one another. Therefore, using #include, the issue of circular dependencies arises. Therefore to avoid this, I attempted to forward declare Level in Entity.h:
class Level { };
However, as Entity needs access to methods in Level, it cannot access such methods, since it does not know they exist. Is there a way to resolve this without re-declaring the majority of Level in Entity?
A proper forward declaration is simply:
class Level;
Note the lack of curly braces. This tells the compiler that there's a class named Level
, but nothing about the contents of it. You can then use pointers (Level *
) and references (Level &
) to this undefined class freely.
Note that you cannot directly instantiate Level
since the compiler needs to know the class's size to create variables.
class Level;
class Entity
{
Level &level; // legal
Level level; // illegal
};
To be able to use Level
in Entity
's methods, you should ideally define Level
's methods in a separate .cpp
file and only declare them in the header. Separating declarations from definitions is a C++ best practice.
// entity.h
class Level;
class Entity
{
void changeLevel(Level &);
};
// entity.cpp
#include "level.h"
#include "entity.h"
void Entity::changeLevel(Level &level)
{
level.loadEntity(*this);
}
you two options:
- use pointers in which case your forward declares should be ok.
- inline the methods of one class, in which case if you include the .h file you can use the methods of the other.
Personally I would go down path number 1, it's cleaner and allows better access. I use a lot of shared_ptr so I do not have to worry about deletes...
Entity.h:
class Level;
class Entity {
private:
Level* m_pLevel;
public:
bool CheckLevel ();
bool WasItThere();
Level.h
class Entity;
class Level {
private:
Entity* m_pEntity;
public:
public bool CheckMyStuff();
public bool CheckItOut() { return m_pEntity->WasItThere();}
}
Entity.cpp
#include "Level.h"
bool Entity::CheckLevel () {
return true;
}
bool Entity::CheckLevel() {
return m_pLevel->CheckMyStuff();
}
bool Entity::WasItThere() {
return true;
}
Level.cpp
bool Level::CheckMyStuff() {
return true;
}
bool Level::CheckItOut() {
return m_pEntity->WasItThere();
}