0

I am still new with c++ and I was told that #pragma once was supposed to take care of circular dependencies

My GameManager.h and GameSetting.h both need to know each other and each have a pointer of the other

for my GameSettings.h i have:

#pragma once
#include "PlayerManager.h"
#include <fstream>
#include "GameManager.h";

class GameSettings {
private:
PlayerManager* pM;
GameManager* gM;
vector<Player*> players;

bool inGame = false;
double betValue = 5;
bool allowSplit = true;
bool allowInsurance = true;
GameSettings(PlayerManager* pM, GameManager* gM) { this->pM = pM; this->gM = gM; }

struct GameSettingData {
    vector<int> playersId;
    double betValue;
    bool allowSplit;
    bool allowInsurance;
};

... function declarations...

for the GameSettings.cpp I only have the #include "GameSettings.h"

And for the GameManager I only have

#pragma once
#include "GameSettings.h"

class GameManager {
private:
    bool isActive = false;
    GameSettings *gS;
public:
    bool getIsActive() { return isActive; }

bool startGame() { return true; }
};

When I remove any mention of GameSettings in GameManager everything work

I mostly know c# so this kind of circular dependencies is kind of new for me. I did try to look at other similar questions but it did not help

Cedric Raymond
  • 69
  • 1
  • 1
  • 9
  • #pragma once deals with circular includes, not circular dependencies between classes. Those you have to fix. – Avi Berger Aug 19 '22 at 23:08
  • Since you are using pointers to reference the classes from each other, this can be solved by using forward declarations. – Avi Berger Aug 19 '22 at 23:11
  • I will have to read about forward declaration. I challenge myself with some small project so I am always more advanced than what I am seeing in school but I may have missed that one – Cedric Raymond Aug 19 '22 at 23:24

1 Answers1

1

Use a forward declaration of GameSettings in GameMager.h. Pointers do not need complete class definitions until they are derefenced.

#pragma once

class GameSettings;

class GameManager {
private:
    bool isActive = false;
    GameSettings *gS;
public:
    bool getIsActive() { return isActive; }

bool startGame() { return true; }
};

GameManager and PlayerManager can also participate in forward declarations in GameSettings.h.

#pragma once
#include <fstream>

class PlayerManager;
class GameManager;

class GameSettings {
private:
PlayerManager* pM;
GameManager* gM;
vector<Player*> players;

bool inGame = false;
double betValue = 5;
bool allowSplit = true;
bool allowInsurance = true;
GameSettings(PlayerManager* pM, GameManager* gM) { this->pM = pM; this->gM = gM; }

struct GameSettingData {
    vector<int> playersId;
    double betValue;
    bool allowSplit;
    bool allowInsurance;
};

Set required #include in .cpp files.

273K
  • 29,503
  • 10
  • 41
  • 64
  • wow thank you, I did not even knew you could do that. how does it work and in what context i should do that? – Cedric Raymond Aug 19 '22 at 23:11
  • it work if i use the line class GameSettings in the gameSettings.h but not if i replace the #include "GameManager.h" by class GameManage in GameSetting.h – Cedric Raymond Aug 19 '22 at 23:16
  • I don't see why it might not work. Maybe the question does not contain an actual code. – 273K Aug 19 '22 at 23:24
  • by trials and error I found that I have to keep the #include "GameManager.h"; in the GameSettings.h. So if I understand, one of the file must reference the other and the other one use forward declaration. – Cedric Raymond Aug 19 '22 at 23:31
  • @CedricRaymond No, there is no such rule. Forward declaration of a class allows you to declare a pointer or a reference to that class and nothing else. If you try to declare an object or call a method of that class, you must have a full class definition (i.e., an `#include`) – Yksisarvinen Aug 20 '22 at 00:17