placeable.h
#include "selectable.h"
class placeable : selectable
{
..
};
selectable.h
#include "game.h"
class selectable
{
..
};
game.h
#include "placeable.h"
class game
{
...
class placeable* holding;
...
};
Basically placeable.h includes selectable.h which includes game.h which includes placeable.h again.
The only solution i can think of is placing the placeable* in a new header, making it static/global and then include this new header in game.h and selectable.h.
I'm sorry i dint include header guards in the upper code. I assumed it was obvious.
Header guards does not help in this case because of the inheritance, same thing goes with forward declaring.
Only include headers if you MUST
Use forward declaration in preference to including:
You only need to include the header for class X iff:
You have a member of the class 'X'
You derive from the class 'X'
You pass a parameter of class 'X' by value.
Otherwise a forward declaration will suffice.
// -> Don't do this #include "placeable.h"
class placeable; // forward declare
// Fine if you are using a pointer.
class game
{
...
class placeable* holding;
...
};
PS. Add header guards.
This means you have not properly encapsulated the functionality of your design. It should be higher-level includes lower level, not same-level includes same-level. If game is the higher level then selectable should not include game.h.
This is a solved problem. It's called header guards. Try this inside ALL of your header files:
#ifndef __NAMEOFTHEFILE_H__
#define __NAMEOFTHEFILE_H__
// nothing goes above the ifndef above
// everything in the file goes here
// nothing comes after the endif below
#endif
Also, you can do this (this is known as a forward reference):
// game.h
class placeable;
class game { ...
placeable* p;
};
There are two problems:
Circular headers dependency. Solution - #ifndef ...
Allocating space for unknown type. Solution - class placeable;
See more here
Use header guards in each of your header files to avoid this problem. In general, your header files should like this:
#ifndef PLACEABLE_H
#define PLACEABLE_H
//
// Class definitions and function declarations
//
#endif
Related
I can't really describe my problem, so I'll show you here with code what I mean:
boxcollider.h
#include "sprite.h"
class BoxCollider
{
public:
BoxCollider(Sprite sprite);
};
sprite.h
#include "boxcollider.h"
class Sprite
{
public:
BoxCollider coll;
};
INCLUDE issue. How can I solve this problem?
You have two issues. One is the circular references between the two classes. The other is just the circular includes. That one is easy.
All your includes -- ALL of them -- should guard against multiple includes. You can do this two ways.
#ifndef BOXCOLLIDER_H
#define BOXCOLLIDER_H
// All your stuff
#endif // BOXCOLLIDER_H
However, all modern C++ compilers I've used support this method:
#pragma once
As the first line in the file. So just put that line at the top of all your include files. That will resolve the circular includes.
It doesn't fix the circular references. You're going to have to use a forward declaration and pass in a reference, pointer, or smart pointer instead of the raw object.
class Sprite;
class BoxCollider
{
public:
BoxCollider(Sprite & sprite);
};
BoxCollider.h should NOT include Sprint.h, but the .CPP file should.
You can solve this issue by using forward referencing. This would work as follows:
boxcollider.h
#ifndef boxcollider(Any word you like but unique to program)
#define boxcollider(same word as used earlier)
#include "sprite.h"
class BoxCollider
{
public:
BoxCollider(Sprite sprite);
};
#endif
sprite.h
#ifndef sprite(Any word you like but unique to program)
#define sprite(same word as used earlier)
class BoxCollider;
class Sprite
{
public:
BoxCollider& coll; // reference or (smart)pointer
};
#endif
Also don't forget the import guards. These prevent you from importing a file more than once.
Forehand I'd like to mention I'm fairly new to C++ programming and that I'm using Ogre3D as framework (for school project reasons).
I have a class Player which inherits from the GameObject class. When trying to build the project I'm confronted with the following error:
Error C2504 'GameObject' : base class undefined - player.h (9)
Which would imply the GameObject class is undefined within the player class' header file. However I have in fact included the GameObject header file in that of the Player (see code below). I am aware circular including is happening in the code. However if I leave out these includes I get a whole list of different errors on which I'm not sure how or why they occur:
I've been stumped on this problem for a few days now and haven't found any solutions around the Internet as of yet (CPlusPlus article I've mainly been consulting: http://www.cplusplus.com/forum/articles/10627/).
The source files for the below listed header files only include their respective header files.
Player.h
#pragma once
#ifndef __Player_h_
#define __Player_h_
#include "GameObject.h"
class Player : public GameObject {
// ... Player class interface
};
#endif
GameObject.h
#pragma once
#ifndef __GameObject_h_
#define __GameObject_h_
#include "GameManager.h"
// Forward declarations
class GameManager;
class GameObject {
// ... GameObject class interface
};
#endinf
The GameObject header includes the GameManager as can be seen.
GameManager.h
#pragma once
// Include guard
#ifndef __GameManager_h_
#define __GameManager_h_
// Includes from project
#include "Main.h"
#include "Constants.h"
#include "GameObject.h" // mentioned circular includes
#include "Player.h" // "
// Includes from system libraries
#include <vector>
// Forward declarations
class GameObject;
class GameManager {
// ... GameManager interface
};
#endif
To top it of there is the Main class which header file looks like the following:
Main.h
// Include guard
#ifndef __Main_h_
#define __Main_h_
// Includes from Ogre framework
#include "Ogre.h"
using namespace Ogre;
// Includes from projet headers
#include "BaseApplication.h"
#include "GameManager.h"
// forward declarations
class GameManager;
class Main : public BaseApplication
{
// ... Main interface
};
#endif
With all the reading I did on the subject and other individuals with the same error I'd figure I would be able to figure it out but yet to no avail. I hope someone can take the time to help me out here and point out any faulty code or conventions.
I think the easiest way to fix the problem is to change your model for including header files. File A.h should only include B.h if B.h defines a symbol that is used (directly) in A.h. It's also generally a bad idea to put a using clause in a header file - let the programmer of the client code make that determination. Drop forward declarations for classes unless they are absolutely necessary; there's no need for the class GameManager right after #include "GameManager.h". I suspect something else is wrong with the code, but the forward declarations for the classes are hiding that problem. If changing the includes does not fix the problem, start with a single .cpp file that includes the "simplest" header (the one that doesn't depend on any others) and build up to the full set of includes.
I am getting stuck using this class, when I used in the main.cpp there is no problem and execute perfectly, but when I use it as a member class the compiler doesn't like it and sends the message "Multiple definition of:"
Here is the class:
RTPSocket.h:
#ifndef RTP_SOCKET_HDR
#define RTP_SOCKET_HDR
namespace RTPConnection
{
enum EMode
{
Sender,
Receiver
};
template<EMode Mode>
class RTPSocket
{
};
}//end namespace
#define RTP_SOCKET_IMP
#include "RTPSocket_Imp.h"//file where i declare the implementation code
#undef RTP_SOCKET_IMP
#endif
this class by itself doesn't have any problem but when i use it in my class, but ....
used in another class
my file.h
#include RTPSocket.h
class CommClass
{
private:
RTPSocket<RTPConnection::Receiver> * mRTPServer;
}
the compiler give this error message:
multiple definition of 'enum RTPConnection::EMode'
this is a method that is declared in another file "rtpsocket_imp.h"
with the guard declared:
template<EMode Mode>
void RTPSocket<Mode>::write(char* aArray,
const size_t aiSize)
{
std::string message("The write function is operative only on Sender Mode");
throw BadTemplate(message);
}
You want include guards around the header:
#ifndef RTPSOCKET_H
#define RTPSOCKET_H
// header contents go here
#endif
This will prevent the header contents from being included more than once per source file, so you will not accidentally get multiple definitions.
UPDATE: Since you say you have include guards, then possible causes of the error might be:
misspelling the include guard name, so it doesn't work
defining something with the same name in another header (or the source file that includes it)
undefining the include guard name.
But without seeing code that reproduces the error, I can only guess what might be wrong.
You need an include guard.
Inside the RTPSocket.h file at the top put
#ifndef RTPSOCKET_INCLUDED
#define RTPSOCKET_INCLUDED
and at the end put
#endif
If that's not the problem, and you do have an include guard, I suggest you search for
enum EMode
in your code and find all the places you have defined it, and make sure you just define it once.
My problem was the CMakeLists.txt that was building this project.
My fault!
I was using forward declaration and includes in one small project.
But sometimes if i created a file.
A that includes C and D.
And then include in B the A, C, D i had some problems, i added the forward declaration to it.
I noticed, that sometimes i just need the forward declaration, it happens because when i previous added it to a file that i includes in the file where the forward declaration is?
Like if i just include in B the A, so the C and D is included too?
I have an class where i just needed to add the forward declaration.
Like:
Class a;
Class b;
Class R{
}
then the file a included the R, so i didn't need to include the a in R, if i did that the code didn't compile. It says something like to declare a class before the {.
Other case is:
A forward declare B, but dont include B and B include A.. it works, i imagine that its because the time the compiler "paste" the A code in B, the forward declaration tells the compiler that the class is there down in the code. If i use ifdef/ifndef and include code b in a it crashes, if i remove the include it works as a charm ^^
Thanks.
Unless you are introducing circular dependencies, which can be broken with forward declarations, just use an #ifndef / #endif pair:
#ifndef _FILE_H_
#define _FILE_H_
/* ... header file specifications ... */
#endif /* _FILE_H_ */
I am too tired to think about all the dependencies you have there, but remember that #include is nothing more than insertion of included file exactly into the place of #include. This is done recursively until all #include directives are expanded.
It is also good to guard against multiple insertions of the same file by typical
#ifndef FILE_H
#define FILE_H
...
#endif
I am making a small game.
In BattleRecord.h:
#ifndef _CHARACTER_H_
#define _CHARACTER_H_
#include "Character.h"
#endif
class BattleRecord
{
public:
Character Attacker;
Character Defender;
Status status;
int DamageDealt;
int GoldEarned;
int ExpGained;
};
In Character.h:
#ifndef _EQUIPMENT_H_
#define _EQUIPMENT_H_
#include "Equipment.h"
#endif
class BattleRecord;
class Character
{
BattleRecord AttackEnemy(Character &Enemy);
}
In BattleRecord.h:
#ifndef _CHARACTER_H_
#define _CHARACTEr_H_
#include "Character.h"
#endif
#ifndef _BATLE_RECORD_H_
#define _BATLE_RECORD_H_
#include "BattleRecord.h"
#endif
class GUI
{
public:
//GUI Methods, and two of these:
void ViewStats(Character &Player);
void Report(BattleRecord Record)
}
The problem here is, my Character.h and BattleRecord.h need to include each other, and this definitely will cause multiple redefinition problem. Therefore, I used forward declaration in Character.h by adding:
class BattleRecord;
The problem is sovled. But then, the GUI.h needs BattleRecord.h again for reporting the battle, so I have to include BattleRecord.h into the GUI.h. I also have to include the Character.h in order to pass into the ViewStat function. I got error and stuck with this up to this piont.
You're using inclusion guards wrong. They should appear in the file that you intend to prevent multiple inclusions only, and they should cover the entire file. (not just the includes).
For example, in BattleRecord.h
#ifndef _BATTLE_H_
#define _BATTLE_H_
#include "Character.h"
class BattleRecord
{
public:
Character Attacker;
Character Defender;
Status status;
int DamageDealt;
int GoldEarned;
int ExpGained;
};
#endif // _BATTLE_H_
Put your #endif at the end of the file not the end of your includes or use #pragma once at the top if your compiler supports this although that is less portable.
Edit:
To further explain what #ifdef & ifndef does is tell the compiler to include or exclude code entirely from compilation.
// if _UNQIUEHEADERNAME_H_ is NOT defined include and compile this code up to #endif
#ifndef _UNQIUEHEADERNAME_H_
// preprocessor define so next time we include this file it is defined and we skip it
#define _UNQIUEHEADERNAME_H_
// put all the code classes and what not that should only be included once here
#endif // close the statement
The reason you want to do this is because including a header file is basically saying "put all the code in this file here" if you did that multiple times then you'd have naming conflicts from redefining objects and slow compile times in the best scenario.
In general, use forward declaration instead of includes. This minimizes how many includes you include file contains. The only exception is when the class you are defining is a derived class, then you need to include the base class.
In addition to the include guard issues mentioned above (you also have a _CHARACTEr_H_/_CHARACTER_H_ mismatch that might cause you trouble on line 2 of GUI.h), you may want to revise your object design so that the Character does not AttackEnemy(), but rather there is a Battle() class where two Characters are referenced and a BattleRecord is produced after the battle. This would prevent the Character class from ever having to know about BattleRecords in the first place, would allow for the possibility of multi-Character battles in the future, having multi-turn battles, or having special battles through inheritance of the Battle class.
OK everyone,
Thanks for helping me. I have rewritten all the inclusions for the header files as suggested, and it works flawless now. Take quite time a bit of time since I did it wrong for many classes.