C++ circular dependency

Started by
5 comments, last by c_olin 12 years, 4 months ago
Hi.

I'm facing a small problem; (in pseudocode:)

class GameEngine
{
class GUIManager;
{
class Button
{
[uses GraphicsManager->AppWindow->GetWidth()]
}
}


class GraphicsManager;
{
AppWindow;

}

}


How can I make use of the graphicsManager, (class that controls all graphics related stuff) inside my button class?
I got some compile errors because Button.h needed the GameEngine.h which needed the GUIManager.h which needed the Button.h.
Advertisement
You can use forward declarations.


// GameEngine.h
#include "GUIManager.h"

class GameEngine { /* ... */ };

// GUIManager.h
#include "Button.h"

class GameEngine;
class Button;

class GUIManager { /* ... */ };

// Button.h
class GameEngine;
class Button;

class Button { /* ... */ };

// GUIManager.cpp
#include "GameEngine.h"

// Button.cpp
#include "GameEngine.h"


Although - maybe it's better to think about whether you really need a GameEngine class. And whether the GUIManager and Button really need to know about the entire engine.
Thanks Telios, you might be right. I'll probabably pass a pointer to the graphicsmanager class to the button class instead of a pointer to the game engine.

I'm not sure whether I need a GameEngine class but I just tought it would be cleaner to separate the game engine from the game logic.
I used to use something similar to this.

I don't know if this is "good practice" but I now pass a pointer to the constructor with any relevant information that class needs.
I don't really know if this would be considered encapsulation but it feels like it =p

I don't know if this is "good practice" but I now pass a pointer to the constructor with any relevant information that class needs.
I don't really know if this would be considered encapsulation but it feels like it =p


I would consider this good practice. With a good design most class will need little to no data passed to the constructor (besides actual parameters for construction).

Unless you mean that you are making a special class to hold what another class requires, which I don't really like the sound of.

Unless you mean that you are making a special class to hold what another class requires, which I don't really like the sound of.


In the case of the OP's example with resolution of the application something that can change during the course of using the app.
If I had a button that had its alignment based on the resolution and it needed to know those parameters and my button setup was a different class than my windows/application class I would (in the constructor) pass a pointer to the original resolution variables on my windows/application class.
int * ResoultionXPTR;
int * ResoultionYPTR;

In the case of the OP's example with resolution of the application something that can change during the course of using the app.
If I had a button that had its alignment based on the resolution and it needed to know those parameters and my button setup was a different class than my windows/application class I would (in the constructor) pass a pointer to the original resolution variables on my windows/application class.
int * ResoultionXPTR;
int * ResoultionYPTR;


In this case I would try to design a way for buttons to define their alignments without directly referencing the screen resolution (perhaps not unlike HTML can be resolution independent). But if the buttons absolutely had to know the screen resolution I would give them a pointer to the active render target when it is being updated rather than raw pointers to integers at construction:


[source lang="cpp"]
// Only construction parameters, no dependencies.
Button::Button(int width, int height, const Vector2& origin) :
width(width), height(height), origin(origin) {
// Initialize the button.
}

void Button::update(const RenderTarget* renderTarget) {
// Cover entire screen.
origin = Vector2(0, 0);

width = renderTarget->getWidth();
height = renderTarget->getHeight();
}
[/source]

However, like I said before, I really don't think a button needs to know about the screen resolution.

This topic is closed to new replies.

Advertisement