• ### Popular Now

• 9
• 11
• 9
• 20
• 12

This topic is 620 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hi all,

I am writing a little 2D battle simulator for practice.

movement (w,a,s,d)

put soldiers for the two different armies (1,2)

start battle (enter)

But I cant run it, and I just cant seem to find the problem with my code.

I am beginner, so probably I am doing something really stupid, which shouldn't be done, but even after researching the error codes, couldn't come up with anything.

Some help would be much appreciated.

My zipped project folder is added to attachments. (Visual Studio)

Thank you.

##### Share on other sites

What do you mean you can't run it?

Does it fail to compile or link?

Does it compile and link correctly, but crash on start-up or at any other specific time?

You mentioned error codes -- what are they? Don't make us work for things you can easily provide.

##### Share on other sites

I am sorry.

It fails to compile. Spent hours trying to figure out the problem. The errors I am getting are not there, they seem like phantoms errors caused by something else. I am guessing I am using pointers wrong and that somehow affects everything, but its just a hunch.

##### Share on other sites

Post mapmanager.h

You can put code in the code tags (the symbol in the text editor that looks like   <>     )

##### Share on other sites
#pragma once
#include <string>
#include <vector>
#include "Soldier.h"

using namespace std;

class MapManager
{
public:
MapManager();
~MapManager();

int placeArmies();
int printMap();
int battle();
Soldier* getClosestEnemy(Soldier* soldier, char self_owner);
void setTile(int x, int y, char c);
char getTile(int x, int y);
void resetTile(int x, int y);

private:
vector <Soldier *> soldiers;
vector <vector<char>> _mapData;
vector <vector<char>> _origMapData;
int cursorX = -1;
int cursorY = -1;
string _path = "Data\\Maps\\";
};


Edited by Odion

##### Share on other sites

Seems alright on its own. However, looking more closely at your error messages it seems like Soldier has a pointer to MapManager, and MapManager has a pointer to Soldier.

This is most likely causing a circular reference (to know what a MapManager is, you need to know what a Soldier is, which needs to know what a MapManager is, etc).

Since you're only using pointers (at least in MapManager), you can forward declare the Soldier class inside MapManager.h. This basically says "somewhere, there is a class called Soldier. You don't need to worry about the details here, because all we currently want is to have a pointer to it".

class Soldier;

In MapManager.cpp you will need to include the Solider.h file to get the proper contents available to you.

Also of note, I would recommend not putting "using namespace std;" in a header. This can cause namespace pollution -- every file that includes MapManager will now suddenly also inherit the using declaration.

If you need to use using declarations, it's best to put them locally -- in the .cpp file.

##### Share on other sites

Thank you. That was the problem....It would have took me days to find it. I also had to put

class MapManager;


in Soldier.h

I took out "using namespace std;" from the headers as well. Thank you for the advice.

I don't understand "Since you're only using pointers.." though. It would be different if I didn't use pointers?

##### Share on other sites
It would be different if I didn't use pointers?

Let's say you add an instance of class Soldier to your class MapManager:

class MapManager
{
Soldier mySoldier;
int myMagicInt;
};

In order to know how large MapManager is (how much memory has to be set aside every time an instance of MapManager is created), we need to know all the details of Soldier. Does it just have an int for HP? Does it have 50 floats with all kinds of stats?

In this case, MapManager would need to know both that Soldier exists, and the details of it.

In the case where you have a pointer to it, all you need to know is that it exists (so it understands that "Soldier" is the name of a class and not just random letters). We still need to know how much memory to set aside for the pointer, however, since all pointers are the same size, it doesn't need to know the details of the class. If the class is huge or tiny, the pointer to it will remain the same size.

The reason why you still need to include Soldier.h in the MapManager.cpp file, is because now you're wanting to access the Soldier details -- mySoldier->someFunction().

To access those details, you need to know they exists, hence the reason for the include here.

This also means you can't have 2 classes which have instances of each other inside each other.

In this case, you would need to split things up somehow, so that either 1 class contains a pointer to the other, or to create a new class which contains both of them.

Edited by Lactose!

##### Share on other sites

I get it. Mostly.

all you need to know is that it exists (so it understands that "Soldier" is the name of a class and not just random letters)

I don't really get why including "Soldier.h" does not provide this information tho'. Isn't including Soldier.h means that that the whole Soldier.h code gets copied into the current block of code?

##### Share on other sites

I don't really get why including "Soldier.h" does not provide this information tho'. Isn't including Soldier.h means that that the whole Soldier.h code gets copied into the current block of code?

That's true, but remember that C++ translation units are compiled from top to bottom and the compiler doesn't know that a symbol exists until it reaches the point where it is declared. If MapManager references Soldier, then Soldier must have been declared (forward or otherwise) before MapManager is. If Soldier is declared after it, the compiler doesn't know it exists at the time that it compiles MapManager. If Soldier IS declared before MapManager, but the compiler can't compile Soldier's definition because it doesn't know what a MapManager is, then the compiler also won't know what a Soldier is when it compiles MapManager because it tried to compile Soldier and failed.

The same thing happens with functions and variables. The following code has the same problem:
void abc()
{
// the compiler doesn't know what xyz is yet
xyz();
}

void xyz()
{
abc();
}

So here again we need a forward declaration:

void xyz();

void abc()
{
// now the compiler knows that xyz is defined somewhere else, so this compiles
xyz();
}

void xyz()
{
abc();
}

Edited by Oberon_Command