My first, immediate problem is with many strange errors that look like this:
In function ZN6BeingC2Ev:
multiple definition of 'area'
first defined here
I am writing a basic pathfinding system and I have two classes:
-Area: Areas describe the 2D grid of walls and open spaces that beings navigate through.
-Graph: Every being capable of pathfinding has its own Graph, and each of those graph objects need to get a part of the layout of the world grid from the currently active Area.
So all Graph objects need to know about *area, which in main() is allocated by the usual area = new Area();
But I can't declare Area *area in main.cpp because Graphs wouldn't be able to see it, and its methods won't be able to read it.
So I tried to declare *area in area.h (shown below). My intention was that because Graph #includes "area.h", area would be known to Graph. This causes my my multiple definitions problem.
I am unsure what exactly the problem is, since I am sure I did not define Area in any way outside of its own header file, and partly because my IDE points me to seemingly unrelated functions when I click the error message for the source of the multiple definition.
So my second question: In the interest of avoiding such an error, is there a better structure that will give Graph knowledge of Area objects and access to their contents?
Below is code which I hope demonstrates my intentions, please let me know if anything necessary has been omitted.
area.h
#ifndef AREA_H_INCLUDED
#define AREA_H_INCLUDED
class Area
{
std::vector<int>wallmap;
...
} *area;
#endif // AREA_H_INCLUDED
graph.h
#ifndef GRAPH_H_INCLUDED
#define GRAPH_H_INCLUDED
#include "area.h"
class Graph
{
...
};
#endif // GRAPH_H_INCLUDED
graph.cpp (The problem is in the switch part)
std::vector<Node*>Graph::RequestPath(int startX, int startY, int destX, int destY);
{
for(std::vector<Node*>::iterator it = nodeGraph.begin(); it != nodeGraph.end(); ++it)
{
(*it)->heuristic = std::abs(destX-startX) + std::abs(destY-startY);
switch(area->wallmap[(*it)->id]) // **I need Graphs to know about the wallmap vector in Area, here for example.**
{
....
}
(*it)->fValue = (*it)->heuristic + (*it)->moveCost;
}
}
main.cpp
#include "area.h"
int main()
{
...
area = new Area();
area->Init();
...
delete area;
...
}
Thanks for your assistance!
As pointed out in a comment by #GManNickG, the problem lies with the use of area as a variable in:
class Area
{
std::vector<int>wallmap;
...
} *area;
Every compilation unit that #includes the .h file will define that variable, which leads to the multiple definition error at link time.
I suggest using a function to get the necessary pointer instead of using a global variable.
class Area
{
std::vector<int>wallmap;
...
};
Area* getArea();
Implement it in the .cpp file that implements the member functions of Area, just to keep related definitions together
Then, you can use the function wherever you were using the global variable.
If you must use a global variable, which I strongly advise against, you can use:
class Area
{
std::vector<int>wallmap;
...
};
extern Area* area;
and make sure that area is defined in the .cpp file that implements the member functions of Area, just to keep related definitions together.
Related
(it is be possible that this question has been asked very often already and i am sorry about this repost, but anything i found just didnt help me, since i am relatively a beginner at c++)
so here is an example to show my problem
i have the class monster
class Monster{
public:
Monster();
void attack();
private:
int _health;
int _damage;
};
and i have the class Level
class Level{
Level();
};
i have created the object "snake" from the class Monster in my "main.cpp"
#include "Monster.h"
int main(){
Monster snake;
}
now what do i do if i want to use "snake" in my "Level" class? if i want to do "snake.attack();" inside of "Level.cpp" for example?
If i declare it again in "Level.cpp" it will be a seperate object with its own attributes wont it?
i have always been making the member functions of my classes static until now, so i could do "Monster::attack();" anywhere in my program but with this tachnique i cant have multiple objects doing different things depending on their attributes (snake1, snake2, bat1, etc...)
thanks for the help in advance!
(and sorry for the possibly reoccuring question)
Presuming those snips are your .h files.
Your level.cpp should something like this:
#include "level.h" // its own header
#include "monster.h" // header with Monster::attack() declaration
Level::DoAttack(Monster& monster) { // using snake as parameter.
health = health - monster.attack(); // monster hits us, subtract health.
}
monster.h would be
class Monster{
public:
Monster();
void attack();
private:
int _health;
int _damage;
};
and monster.cpp
Monster::attack() {
// code to calculate the attack
}
I could not completely understand your questions.But from what I understood.I think you want to access a Monster object instantiated in main() to be used inside level.So,here is what you can do.Add a constructor inside the level class which takes a monster object as an argument.Then instantiate a level object and pass the monster object in it.Like this,
Level l=new Level(snake);
By declaring a class you're not creating any objects. You normally declare a class by including the corresponding header file.
So, in Level.h you'd #include <Monster.h>, then you can reference it inside Level.
But seriously, you can't write much C++ code without understanding the basic things such as declaration vs. definition, header files (.h), classes vs. objects, pointers and references, etc. It would be best to invest in a book or at least to read some tutorials online.
I'm trying to make class functions I can tack on to other classes, like with nested classes. I'm still fairly new to C++, so I may not actually be trying to use nested classes, but to the best of my knowledge that's where I'm at.
Now, I've just written this in Chrome, so it has no real use, but I wanted to keep the code short.
I'm compiling on Windows 7, using Visual Studio 2015.
I have two classes in file_1.h:
#pragma once
#include "file_2.h"
class magic_beans{
public:
magic_beans();
~magic_beans();
int getTotal();
private:
double total[2]; //they have magic fractions
}
class magic_box{
public:
magic_box(); //initiate
~magic_box(); //make sure all objects have been executed
void update();
magic_beans beans; //works fine
magic_apples apples; //does not work
private:
int true_rand; //because it's magic
};
... And I have one class in file_2.h:
#pragma once
#include "file_1.h"
class magic_apples{
public:
magic_apples();
~magic_apples();
int getTotal();
private:
double total[2];
}
Now, I've found that I can simply change:
magic_apples apples;
To:
class magic_apples *apples;
And in my constructor I add:
apples = new magic_apples;
And in my destructor, before you ask:
delete apples;
Why must I refer to a class defined in an external file using pointers, whereas one locally defined is fine?
Ideally I would like to be able to define magic_apples the same way I can define magic_beans. I'm not against using pointers but to keep my code fairly uniform I'm interested in finding an alternative definition method.
I have tried a few alternative defines of magic_apples within my magic_box class in file_1.h but I have been unable to get anything else to work.
You have a circular dependency, file_1.h depends on file_2.h which depends on file_1.h etc. No amount of header include guards or pragmas can solve that problem.
There are two ways of solving the problem, and one way is by using forward declarations and pointers. Pointers solve it because using a pointer you don't need a complete type.
The other way to solve it is to break the circular dependency. By looking at your structures that you show, it seems magic_apples doesn't need the magic_beans type, so you can break the circle by simply not includeing file_1.h. So file_2.h should look like
#pragma once
// Note no include file here!
class magic_apples{
public:
magic_apples();
~magic_apples();
int getTotal();
private:
double total[2];
}
This question already has answers here:
Resolve build errors due to circular dependency amongst classes
(12 answers)
Cross referencing included headers in c++ program
(5 answers)
Closed 9 years ago.
For example a little Computergame with three Classes Player, Bot and Game
Player has a Method that checks if the Player collide with a bot
// Player.h
#include Game.h
#include Bot.h
class Player {
private:
bool collision(Game g) {
for (Bot bot: g.bots)
...
}
};
The Bot.h (kept simple, of cause it has some other attributes like actual position and so far)
// Bot.h
class Bot {
public:
Bot()
};
The Gameclass handles the Gameloop and the List of Bots
//Game.h
#include Bot.h
#include Player.h
class Game {
public:
Player player:
std::vector<Bot> bots
void loop() { player.collision() }
};
So here we have the problem that Game.h includes Player.h and the other way around.
How can I resolve this?
While the other answers here are certainly technically correct, whenever I come across a situation like this I see it as pointing out a potential flaw in my design. What you have is cyclic dependencies, like so:
This isn't just a problem for your implementation, it means that there is too much coupling between classes, or, conversely, too little information hiding. This means that you can't design the Player independently of the Game, for example.
So if possible, I'd prefer a situation like this, where the Game, as the controller delegates work out to other classes.
One way to do this is for the Game to pass references to its own properties as and when the Player needs them.
For example have collision take a bots parameter rather than the `Game
bool collision(const std::vector<Bot&> bots) {
// note pass objects by const ref is usu preferred in C++ to pass by value
for (Bot bot: g.bots)
...
}
(Note in a more sophisticated approach, it could pass interfaces, i.e. abstract base classes, onto itself).
If all else fails, you can go back to using a forward declaration.
In this case the easiest thing would be a forward declaration, and moving some code from the header file to the source file.
Like this
Player.h
#include "Bot.h"
class Game; // forward declaration
class Player {
private:
bool collision(Game g);
};
Player.cpp
#include "Player.h"
#include "Game.h"
bool Player::collision(Game g) {
for (Bot bot: g.bots)
...
}
The forward declaration tells the compiler that Game is the name of a class but nothing else. So the Player::collision method must be moved to the Player.cpp file where the full definition of Game is available.
I dont think you can do this since If A contains B, and B contains A, it would be infinite size. Infact you can create two classes that store pointers to one another, by using the forward declaration, so that the two classes know of each other's existence
Forward declaration is required - http://en.wikipedia.org/wiki/Forward_declaration
I wrote a C++ DLL using VS 2010 which is used to wrap some program that does boolean operations on polygons.Its structure is as follows: There is a main header and .cpp whose methods are exposed by marks :
__declspec(dllexport)
Then inside one of those method I execute a call of one of the methods of my polygon program which is contained in a different c++ class which is a part of the library.I should note that in addition to calling that method I also create(in the main dll .cpp file) variables which are defined in that polygons program.Those variables are of types required to pass and receive numeric data from the polygon program.
Now ,what is wrong.When I run the an application that uses this dll I do two identical calls to the same method of the library -the one I explained above that calls a function of the polygon program.When I do those calls I pass some numeric data into the method and expect to get back a new data based on some calculations in the polygons program.First call returns the correct data but the second one returns kind of mix of the data from the first call and the second input data.I am not DLL expert but I took a look at this thread :
How do I use extern to share variables between source files?
And I wonder if that may be the source of the problem? As I mentioned I use some variables which are part of the polygon calculation class and I instantiate them in the main .cpp of the dll. Two of those variables take the input data from the user and get it into the method that calculates the result and the third variable is filled with the result returned by that function.
Any help will be greatly appreciated as I am really stuck with it at the moment.
EDIT: The variables I use from the polygon source class are defined in its header as follows:
typedef std::vector< IntPoint > Polygon;
typedef std::vector< Polygon > Polygons;
DLL Test program
#include "stdafx.h"
#include "Clipper_lib.h"
int _tmain(int argc, _TCHAR* argv[])
{
int subj[]={100,100,200,100,200,200,100,200};
int clip[]={100,100,200,100,200,200,100,200};
vector<vector<int>> solution;
vector<vector<int>> solution1;
Execute(subj,clip,solution);
Execute(subj,clip,solution1);
return 0;
}
DLL header :
#include "clipper.hpp" /// this is the working C++ class of polygons operations
#include <vector>
using namespace ClipperLib;
using namespace std;
extern Polygon subj;
extern Polygon clip;
extern Polygons solution;
extern "C"
{
__declspec(dllexport) void Execute(int subj[],int clip[],vector<vector<int>> &solution);
}
DLL .cpp
// Clipper_lib.cpp : Defines the exported functions for the DLL application.
//
#include "Clipper_lib.h"
Clipper clipper;
void Execute(int subj[],int clip[],vector<vector<int>> &solution){
Polygon *subjP=new Polygon();
Polygon *clipP=new Polygon();
Polygons *solutionP=new Polygons();
for(int i=0; i<8;i+=2){
subjP->push_back(IntPoint(subj[i],subj[i+1]));
}
for(int b=0;b<8;b+=2){
clipP->push_back(IntPoint(clip[b],clip[b+1]));
}
clipper.Clear();
clipper.AddPolygon(*subjP,ptSubject);
clipper.AddPolygon(*clipP,ptClip);
clipper.Execute(ctIntersection,*solutionP);
for( vector<Polygon>::size_type d=0;d!=solutionP->size();++d){
vector<int> poly;
solution.push_back(poly);
for(vector<IntPoint>::size_type k=0;k!=solutionP[d].size();++k){
for(vector<IntPoint>::size_type s=0;s!=solutionP[d][k].size();++s){
int numX=(int)solutionP[d][k][s].X;
int numY=(int)solutionP[d][k][s].Y;
solution[d].push_back(numX);
solution[d].push_back(numY);
}
}
}
delete solutionP;
delete subjP;
delete clipP;
}
Well .Figured it out.Because the wrapper of this source was C based API I had to embrace all the C++ methods in the DLL with extern "C" .This way it works fine.Thanks for all the comments anyways .
The easier thing to do: after you used data from Polygons call clear() on it. clear() it's a fast method that keep allocated memory (in case you fear for efficiency) but mark the content as unavailable. So you can fill Polygons with new data without problems. Inner vectors, i.e. objects of type Polygon, will clear on request, you can ignore these.
Can you not debug your library call?
Eg. step through it in a debugger and try and see where the invalid values are getting set. Many IDE's let you set breakpoints that fire when data at a particular memory location changes. You could set a breakpoint on a value that you know gets set incorrectly on the second call, and it will show you what is changing it.
Will using same class name within multiple namespaces get me into trouble? I also try to remove dependency to math library. What do you think about following design.
first file
#define MATH_RECTANGLE_EXISTS
namespace math {
class Rectangle : Object2D {
public:
float perimeter();
float area();
float x,y,w,h;
};
}
other file
#define GRAPHIC_RECTANGLE_EXISTS
#ifndef MATH_RECTANGLE_EXISTS
//is this a good idea to remove dependency?
namespace math {
class Rectangle {
public:
float x,y,w,h;
}
}
#endif
namespace graphics {
class Rectangle : math::Rectangle {
public:
void Draw(Canvas &canvas);
void Translate(float x, float y);
};
}
EDIT
What about this approach to remove dependency?
** 1st file**
namespace common {
class Rectangle {
float x,y,w,h;
};
}
math lib file
#define MATH_RECTANGLE_EXISTS
namespace math {
class Rectangle : public common::Rectangle, public Object2D {
public:
float perimeter();
float area();
};
}
graphic file
#define GRAPHIC_RECTANGLE_EXISTS
namespace graphics {
#ifndef MATH_RECTANGLE_EXISTS
class Rectangle : public math::Rectangle {
#else
class Rectangle : public common::Rectangle {
#endif
public:
void Draw(Canvas &canvas);
void Translate(float x, float y);
};
}
Thanks in advance.
I don't see the problem with reusing the same identifier within different namespaces, that was they were created for after all.
However I would strongly urge you NOT to 'simulate' the inclusion of math::Rectangle. If you need the file then include it, but what you are doing is called copy/paste programming, and it leads to a good number of problems, essentially because your two pieces of code are not synchronized so any bug fix / feature addition to one is not reported on the other.
EDIT: answer to the Edit ;)
It is not clear from the comments so I will state it:
If you need the dependency (because you really USE the functionality offered), then you HAVE to include the header. On the other hand, if you only use inheritance to get something that have 4 corners and nearly no method, then you're better up rolling a new Rectangle class with the minimum functionality.
I can think of an edge case though. I am under the impression that you are not so much interested in the functionality but in fact interested in the possibility of reusing the methods in the Math library that have been tailored to take a math::Rectangle as a parameter.
According to Herb Sutter (in C++ Coding Standards I think), the free functions that are bundled with a class are part of the class public interface. So if you want those classes, you actually need the inheritance.
Now I can understand that you may have some reluctance in including a library that may be huge (I don't know your Math library). In this case you could consider splitting the Math library in two:
A MathShapes library, comprising the basic shapes and the methods that act upon them
A Math library, which includes MathShapes and add all the other stuff
This way you would only depend on the MathShapes library.
On the other hand, if you absolutely do not want the dependency, then a blunt copy/paste will do, but your solution of testing the presence of Math::Rectangle by testing the presence of its header guard is ill-fitted:
It only works if you get the header guard correctly
AND if the include is actually performed BEFORE the include of Graphics::Rectangle
Note that in the case in which Graphics::Rectangle is included before Math::Rectangle you may have some compilation issues...
So make up your mind on whether or not you want the dependency.
That is rather what namespaces are for, and a rectangle is both a mathematical and a graphical object.
The attempt to avoid including a header file however is very ill-advised. It achieves nothing other than a maintenance headache. A change in math::Rectangle should cause a rebuild of graphics::Rectangle - if they end up in a mismatch and you hide that from the compiler, you'll end up with a harder to debug run-time error.