How do you prevent continuously looping #include statements?
I have a problem with two classes that each need to know about the other in their header file.
Structure.h
#ifndef STRUCTURE_H
#define STRUCTURE_H
#include <vector>
#include "Sprite.h"
#include "Bullet.h"
class Structure: public Sprite{
public:
Structure(const BITMAP bm, const Vec2& pos, const Vec2& vel,
const RECT boundaries, std::vector<std::vector<bool>> holes);
virtual ~Structure() = 0;
void takeDamage(const Bullet* bullet);
protected:
std::vector<std::vector<bool>> mBulletHoles;
};
#endif
Structure.cpp
#include "Structure.h"
Structure::Structure(const BITMAP bm, const Vec2& pos, const Vec2& vel,
const RECT boundaries, std::vector<std::vector<bool>> holes)
:Sprite(bm, pos, vel, boundaries),
mBulletHoles(holes)
{}
void Structure::takeDamage(const Bullet* bullet){
}
Sprite::~Sprite(){}
Bullet.h
#ifndef BULLET_H
#define BULLET_H
#include "Animate.h"
#include "Structure.h"
class Bullet: public Sprite{
public:
Bullet(const BITMAP bm, const Vec2& pos, const Vec2& vel, const RECT boundaries,
bool friendly);
virtual ~Bullet();
int checkCollision(Animate* target);
void checkCollision(Structure* target, float dt);
private:
float mTimeSinceCollision;
bool mFriendly;
bool mActive;
const static float mPenetrationTime;
};
#endif
Bullet.cpp
#include "Bullet.h"
Bullet::Bullet(const BITMAP bm, const Vec2& pos, const Vec2& vel,
const RECT boundaries, bool friendly)
:Sprite(bm, pos, vel, boundaries),
mTimeSinceCollis开发者_如何学JAVAion(0.0f),
mFriendly(friendly),
mActive(true)
{}
int Bullet::checkCollision(Animate* target){
int returnPoints = 0;
if((target->identifier() == "Player") && !mFriendly){
if(isTouching(target)){
target->takeDamage();
mActive = false;
}
}else if((target->identifier() == "Alien") && mFriendly){
if(isTouching(target)){
returnPoints = target->takeDamage();
mActive = false;
}
}
return returnPoints;
}
void Bullet::checkCollision(Structure* target, float dt){
if(isTouching(target)){
mTimeSinceCollision += dt;
target->takeDamage(this);
}
if(mTimeSinceCollision >= mPenetrationTime){
mActive = false;
}
}
Bullet::~Bullet(){}
const float Bullet::mPenetrationTime = .05;
because the two header files call each other, I am getting many errors. I tired replacing
#include "Bullet.h"
in Structure.h with
class Bullet;
but then the compiler said I had multiply defined types. How are you supposed to get around the looping #include statements?
First, you want to avoid those circular include. Then, if really there is no way out, you simply declare the class you need in the header.
For instance, in the Bullet.h :
#include "Sprite.h"
class Structure; // Can now use Structure* and Structure&
class Bullet {
...
}
In Bullet.cpp
#include "Bullet.h"
#include "Structure.h"
In the Structure.h :
#include "Sprite.h"
class Bullet; // Can now use Bullet* and Bullet&
class Structure {
...
}
In Structure.cpp
#include "Structure.h"
#include "Bullet.h"
When the compiler will see the unknown "Sprite" object in the Bullet implementation, he'll know you're referring to a particular object, since you declared in the header. See in the C++ FAQ Lite for instance.
the problem is you're including the headers within each other. I.e you're including structure in bullet and vice versa, which is causing a multiple inclusion error. The inclusion guards you have up top prevent this, but I still find it happens in some cases, this being one of them.
In a header file, if you do not have anything other than pointers to that class (members and/or parameters / return types), you can use the forward declaration instead of including the header:
class Bullet;
You still need to include both Structure.h and Bullet.h in the cpp file, because it needs the full definition for both.
Use a pointer to the class instead of the class in one of the files and allocate it through new
(and delete
it in the dtor, ofc).
The thing is, the size of a pointer is ALWAYS known to the compiler, so it won't complain and compile your code. This is called forward declaration. It's very well documented.
adding #pragma once would help, but having a better include structure to avoid loops would be good too.
#pragma once makes sure the current file is included only once in a single compilation, for more info on #pragma once visit http://en.wikipedia.org/wiki/Pragma_once
精彩评论