• Advertisement
Sign in to follow this  

Please Help Me Find The Bugs

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

If you intended to correct an error in the post then please contact us.

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 this post


Link to post
Share on other sites
Advertisement

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 this post


Link to post
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.

Screenshot_15.png

Share this post


Link to post
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 this post


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

using namespace std;

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

	int loadMap(string mapName);
	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 this post


Link to post
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".

 

Before class MapManager, add

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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement