2

I've been programming a Monopoly game for a final project. So I thought I was on a roll, and that I had everything figured out with my psuedocode. But, it seems I forgot how to deal with includes properly, I know that is the issue since I was able to refine it to that point, but I'm not sure how to fix it.

In this super stripped down version of my code I have three .h files "Space.h" which is an abstract/virtual class which has to be inherited by a variety of different spaces that can appear on a typical Monopoly board: properties, jail, taxes, Chance, Community Chest, etc. The function that has to be inherited is run(Player&) which is what is "run" when you land on that particular space on the board, all functions that use run use a player passed by argument.

#pragma once
#include <string>
#include "Player.h"

class Space
{
public:
    virtual void run(Player&) = 0;
};

My second .h file is the "Property.h" this inherits from Space

#pragma once
#include "Space.h"

class Property : Space
{
public:
    void run(Player&) override;
    int i{ 0 };
};

Lastly I have the "Player.h" which has two variables a name and a vector of properties it owns.

#pragma once
#include <string>
#include <vector>
#include "Property.h"

class Player
{
public:
    std::string name{ "foo" };
    void addProperty(Property p);
private:
    std::vector <Property> ownedProperties;
};

Here's a very basic Property implementation

#include "Property.h"
#include <iostream>

void Property::run(Player & p)
{
    std::cout << p.name;
}

Player implementation

#include "Player.h"
#include <iostream>

void Player::addProperty(Property p)
{
    ownedProperties.push_back(p);
}

And finally main

#include "Player.h"
#include "Space.h"
#include "Property.h"

int main()
{
    Player p{};
    Property prop{};
    prop.run(p);
    system("pause");
}

Every time this is run I get a slew of errors, I'm sure it's got to do something with the circular include logic, with player including property, and property including space, which includes player. But, I don't see a workaround considering #include is needed to know how everything is defined isn't? Or are these errors referring to something else?

enter image description here

JonathanDavidArndt
  • 2,518
  • 13
  • 37
  • 49
Alex
  • 620
  • 1
  • 6
  • 20
  • Using --> to mean "depends on in some form or other", you have: `Space --> Player --> Property --> Space --> Player --> Property --> Space` etc. This is a circular dependency causing immediate difficulties, but more importantly it's the sort of thing that makes it very difficult to reason about what's going on in your code. The modularisation you have applied is almost pointless, because the "modules" are all inter-dependent making it a BBoM. _I suggest you rethink your design. Perhaps try drawing it out on a sheet of paper with responsibilities and dependencies._ – Disillusioned Dec 08 '17 at 03:00

1 Answers1

2

You have a circular include problem. Player includes Property which includes Space which includes Player again.

You can break the circle by not including Player.h in Space.h and only forward declare the class

#pragma once

class Player;

class Space
{
public:
    virtual void run(Player&) = 0;
};
Bo Persson
  • 90,663
  • 31
  • 146
  • 203
  • Thanks for the advice, however, it just seemed to push the problem to Property.h. Since Player.h was no longer defined in Property.h, I had to include player in Property.h but that just opens up another infinite loop only between two classes this time, property needs player to function and player needs property to function, how do I break out of the loop when they need each other included in order to function? – Alex Dec 08 '17 at 03:43
  • 1
    No, you don't have to include the header just to pass a reference. You can include all the headers as needed in the .cpp files, where the functions are implemented. – Bo Persson Dec 08 '17 at 03:48
  • 1
    Oh! I get it! Include it in the .cpp files, now it works perfectly! OMG! Thank you! :) Glad something like forward declaration exists! – Alex Dec 08 '17 at 03:53