Jode
Jode

Reputation: 92

Circular Class Dependency with Includes

Here is basically what my class layout is:

GameDriver.h:

#ifndef GAMEDRIVER_H
#define GAMEDRIVER_H
#include "CameraSystem.h"

class CameraSystem; //Forward declaration

class GameDriver {
    //Stuff
};

#endif

CameraSystem.h:

#ifndef CAMERASYSTEM_H
#define CAMERASYSTEM_H
#include "Tickable.h"

class GameDriver;
class CameraSystem: public Tickable { //Complains here
    //Stuff
};

#endif

Tickable.h:

#ifndef TICKABLE_H
#define TICKABLE_H
#include "GameDriver.h"
class GameDriver;
class Tickable {
    //Stuff
};

#endif

Here is the error I get:

CameraSystem.h:9 error: expected class-name before '{' token

Forward declaring Tickable does not work either. Any help? Thanks in advance.

Upvotes: 0

Views: 135

Answers (5)

JoeG
JoeG

Reputation: 13182

You can't inherit from a class that has not been declared.

Pre-processing Tickable.h gives you:

class GameDriver;
class CameraSystem: public Tickable { //Complains here
    //Stuff
};

class CameraSystem; //Forward declaration

class GameDriver {
    //Stuff
};

class GameDriver;
class Tickable {
    //Stuff
};

See how Tickable hasn't even been forward declared when you inherit from it?

Upvotes: 0

cli_hlt
cli_hlt

Reputation: 7164

Ok, I see two problems here.

First: Your forward declarations are useless. You are writing (using GameDriver.h: as an example):

#include "CameraSystem.h"

class CameraSystem; //Forward declaration

class GameDriver {
    //Stuff
};

Here CameraSystem will already be known by including CameraSystem.h, so the forward declaration is nonsense. What you meant to write was:

class CameraSystem; //Forward declaration

class GameDriver {
    //Stuff
};

Second: Where you really would need a forward declaration you cannot use it, as you cannot derive from a forward declared class:

#include "Tickable.h"

class CameraSystem: public Tickable { //Complains here
    //Stuff
};

Note that a forward declaration works only if you are not using the forward declared class directly as a class member. You are then restricted to pointers or references to the forward declared class. The reason for this is, that the compiler does not know the memory layout of the class unless its completely known (i.e. by including the header file). For example:

class CameraSystem;
class GameDriver {
  CameraSystem m_cameraSystem;
};

will NOT work. However,

class CameraSystem;
class GameDriver {
  CameraSystem *m_cameraSystem;
  CameraSystem& m_otherCameraSystem;
};

will. Of course you will still have to include the correct header files in your *.cpp file.

Upvotes: 1

Mario
Mario

Reputation: 36487

You can't resolve such circular dependencies. However, you've got the solution (partially):

I.e. instead of including a header, just use a forward declaration. If you do this right, there shouldn't be any issues. However, try to group your program into logical elements/groups and only add cross-references if they're requied (e.g. the game has to know about and access the camera, but the camera shouldn't have to access the game system as a whole).

Upvotes: 0

juanchopanza
juanchopanza

Reputation: 227390

If you forward delcare a class you shouldn't include the class' header.

#include "CameraSystem.h" // DO NOT INCLUDE THIS

class CameraSystem; //Forward declaration

class GameDriver {
    //Stuff
};

Upvotes: 3

Eran Zimmerman Gonen
Eran Zimmerman Gonen

Reputation: 4507

Try adding #pragma once at the very beginning of each header file.

You should somehow tell the compiler to only put those once. That's one way. Another is using #ifndef X and #define X.

If this doesn't solve it, try to just eliminate the circular dependency - it doesn't seem like it has to happen...

Upvotes: -2

Related Questions