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.
Related
Suppose I have two data structures that reference each other. I want to put them into their separate header files like this:
// datastruct1.h
#ifndef DATA_STRUCT_ONE
#define DATA_STRUCT_ONE
#include <datastruct2.h>
typedef struct DataStructOne_t
{
DataStructTwo* two;
} DataStructOne;
#endif
and
// datastruct2.h
#ifndef DATA_STRUCT_TWO
#define DATA_STRUCT_TWO
#include <datastruct1.h>
typedef struct DataStructTwo_t
{
DataStructOne* one;
} DataStructTwo;
#endif
and I have a main function:
#include <datastruct1.h>
#include <datastruct2.h>
int main()
{
DataStructOne* one;
DataStructTwo* two;
}
However my compiler complains:
$ gcc -I. -c main.c
In file included from ./datastruct1.h:4,
from main.c:1:
./datastruct2.h:8:2: error: unknown type name ‘DataStructOne’
8 | DataStructOne* one;
| ^~~~~~~~~~~~~
Why is that? What can I do to fix this?
Why?
In order to understand why, we need to think like a compiler. Let's do that while analysing main.c line by line. What would a compiler do?
#include <datastruct1.h>: Put "main.c" aside (push to the stack of files being processed) and switch to "datastruct1.h"
#ifndef DATA_STRUCT_ONE: hmm, this is not defined, let's continue.
#define DATA_STRUCT_ONE: OK, defined!
#include <datastruct2.h>: Put "datastruct1.h" aside and switch to "datastruct2.h"
#ifndef DATA_STRUCT_TWO: hmm, this is not defined, let's continue.
#define DATA_STRUCT_TWO: OK, defined!
#include <datastruct1.h>: Put "datastruct2.h" aside and switch to "datastruct1.h"
#ifndef DATA_STRUCT_ONE: this is now defined, so go straigh to #endif.
(end of "datastruct1.h"): close "datastruct1.h" and pop current file from the stack of filles. What were I doing? Ahh, "datastruct2.h". Let's continue from the place where we left.
typedef struct DataStructTwo_t ok, starting a struct definition
DataStructOne* one; Wait, what is DataStructOne? We have not seen it? (looking up the list of processed lines) Nope, no DataStructOne in sight. Panic!
What happened? In order to compile "datastruct2.h", the compiler needs "datastruct1.h", but the #include guards in it "datastruct1.h" prevent its content from being actually included where it's needed.
The situation is symmetrical, so if we switch the order of #include directives in "main.c", we get the same result with the roles of the two files reversed. We cannot remove the guards either, because that would cause an infinite chain of file inclusions.
It appears that we need "datastruct2.h" to appear before "datastruct1.h" and we need "datastruct1.h" to appear before "datastruct2.h". This does not seem possible.
What?
The situation where file A #includes file B which in turn #includes file A is clearly unacceptable. We need to break the vicious cycle.
Fortunately C and C++ have forward declarations. We can use this language feature to rewrite our header files:
#ifndef DATA_STRUCT_ONE
#define DATA_STRUCT_ONE
// No, do not #include <datastruct2.h>
struct DataStructTwo_t; // this is forward declaration
typedef struct DataStructOne_t
{
struct DataStructTwo_t* two;
} DataStructOne;
#endif
In this case we can rewrite "datastruct2.h" the same way, eliminating its dependency on "datastruct1.h", breaking the cycle in two places (strictly speaking, this is not needed, but less dependencies is always good). Alas. this is not always the case. Often there is only one way to introduce a forward declaration and break the cycle. For ecample, if, instead of
DataStructOne* one;
we had
DataStructOne one; // no pointer
then a forward declaration would not work in this place.
What if I cannot use a forward declaration anywhare?
Then you have a design problem. For example, if instead of both DataStructOne* one; and DataStructTwo* two; you had DataStructOne one; and DataStructTwo two;, then this data structure is not realisable in C or C++. You need to change one of the fields to be a pointer (in C++: a smart pointer), or eliminate it altogether.
One way to resolve the circular dependency and still use the typedefs where possible is to split the headers into two parts with a separate guard macro for each part. The first part provides typedefs for incomplete struct types and the second part completes the declarations of the struct types.
For example :-
datastruct1.h
#ifndef DATA_STRUCT_ONE_PRIV
#define DATA_STRUCT_ONE_PRIV
/* First part of datastruct1.h. */
typedef struct DataStructOne_t DataStructOne;
#endif
#ifndef DATA_STRUCT_ONE
#define DATA_STRUCT_ONE
/* Second part of datastruct1.h */
#include <datastruct2.h>
struct DataStructOne_t
{
DataStructTwo *two;
};
#endif
datastruct2.h
#ifndef DATA_STRUCT_TWO_PRIV
#define DATA_STRUCT_TWO_PRIV
/* First part of datastruct2.h. */
typedef struct DataStructTwo_t DataStructTwo;
#endif
#ifndef DATA_STRUCT_TWO
#define DATA_STRUCT_TWO
/* Second part of datastruct2.h */
#include <datastruct1.h>
struct DataStructTwo_t
{
DataStructOne *one;
};
#endif
main.c
/*
* You can reverse the order of these #includes or omit one of them
* if you want.
*/
#include <datastruct1.h>
#include <datastruct2.h>
int main(void)
{
DataStructOne *one;
DataStructTwo *two;
}
As mentioned in the comment in main.c above, only one of the headers needs to be included since the other header will be included indirectly anyway.
Well, if both structures reference each other, it is clear that they must be related. The best thing you can do is to put both in one include file (as they are related) but putting them in different and making the compiler to read from one include the other will make the compiler to read the main file... .from main file start reading include A until it gets to the point to include B, and start reading B to the point of the include A again(we'll start reading A again in a recursive manner that has no end) you will never stop reading each file and worse, you will get an error the second time you see the same struct definition (because it has been already defined before)
To allow the user to include any or both files without a problem, a define is made when include file A is encountered:
File A.h
#ifndef INCLUDE_FILE_A
#define INCLUDE_FILE_A
/* ... the whole stuff of file A with the proper includes of other files.*/
#include "B.h"
#endif /* INCLUDE_FILE_A */
and in
File B.h
#ifndef INCLUDE_FILE_B
#define INCLUDE_FILE_B
/* ... the whole stuff of file B with the proper includes of other files.*/
#include "A.h"
#endif /* INCLUDE_FILE_B */
so the definitions made in file A are only used if INCLUDE_FILE_A has not been included previously, and skip them if file A has been included already (and the same for B.h, of course).
If you make the same on file B (but instead with INCLUDE_FILE_B) then you will be secure that both files will be included in either order (depending on how you did it in the first case) and will never be included again (making th e inclussion secure of returning back to the main file.
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!
Let's say I want to compile something like this:
//Prova.h:
//--------------------
#ifndef _PROVA_
#define _PROVA_
#include "Terza.h"
class Prova{
public:
Prova();
};
#endif
and
//Terza.h:
//--------------------
#ifndef _TERZA_
#define _TERZA_
#include "EreProva.h"
class Terza{
public:
Terza();
};
#endif
and
//EreProva.h:
//--------------------
#ifndef _EREPROVA_
#define _EREPROVA_
#include "Prova.h"
class EreProva : public Prova{
public:
EreProva();
};
#endif
which doesn't compile saying "'Prova' : base class undefined".
What is the best way to avoid recursion of header between inherited classes?
If you need to have cyclic dependencies there is something wrong with your design and you should revisit your design and try to remove such complex and unwanted cyclic dependencies.
One of overcoming cyclic dependencies is to use Forward Declarations, but note that once you forward declare a type the type becomes Incomplete type for the compiler and there are limitations about what operations you can do with it. You cannot perform any operations on that type instances which need the compiler to know the memory layout of the type.
Good Read:
When can I use a forward declaration?
Sometimes you can work around problems of this sort by tring the following: (1) try adding the "#pragma once" directive at the top of your files, although this may be compiler specific (I used it when developing in VC++ some time ago) (2) instead of including the header files in the class, you can try just add "class Prova", or whatever class it is, to indicate a class which you will define later on but want to "use" now.
Although as Als says, it is better to avoid such designs.
In this code:
//Prova.h:
//--------------------
#ifndef _PROVA_
#define _PROVA_
#include "Terza.h"
class Prova{
public:
Prova();
};
Since you don't use the Tezra class in any way, you don't need the #include. Take it out. Also, you are missing and #endif. Close the #ifndef in this file with a matching #endif in this file.
Moreover:
//Terza.h:
//--------------------
#ifndef _TERZA_
#define _TERZA_
#include "EreProva.h"
class Terza{
public:
Terza();
};
#endif
#endif
You also don't use the EreProva class in this file at all -- so take out the #include statement. You also have an extra #endif at the end of the file. There is only one #ifndef here, so there should only be one #endif. Take the last one out.
#include "DLLDefines.h"
#include "DLLDefines.h"
The above actually passed compilation, but why?
Well, it's legal because it has to be legal. Because you often include the same header multiple times without even realizing it.
You might include two headers in a .cpp file, each of which include a number of files, some of which might be included by both.
For example, all the standard library headers (say, string or vector for example) are probably included in most of your headers. So you quickly end up with the same header being indirectly included multiple times in the same .cpp file.
So in short, it has to work, or all C++ code would fall apart.
As for how it works, usually through include guards. Remember that #include just performs a simple copy/paste: it inserts the contents of the header file at the #include site.
So let's say you have a header file header.h with the following contents:
class MyClass {};
now let's create a cpp file which includes it twice:
#include "header.h"
#include "header.h"
the preprocessor expands this to:
class MyClass {};
class MyClass {};
which obviously causes an error: the same class is defined twice. So that doesn't work. Instead, let's modify the header to contain include guards:
#ifndef HEADER_H
#define HEADER_H
class MyClass {};
#endif
Now, if we include it twice, we get this:
#ifndef HEADER_H
#define HEADER_H
class MyClass {};
#endif
#ifndef HEADER_H
#define HEADER_H
class MyClass {};
#endif
And this is what happens when the preprocessor processes it:
#ifndef HEADER_H // HEADER_H is not defined, so we enter the "if" block
#define HEADER_H // HEADER_H is now defined
class MyClass {};// MyClass is now defined
#endif // leaving the "if" block
#ifndef HEADER_H // HEADER_H *is* defined, so we do *not* enter the "if" block
//#define HEADER_H
//
//class MyClass {};
//
#endif // end of the skipped "if" block
So, the end result is that MyClass got defined only once, even though the header was included twice. And so the resulting code is valid.
This is an important property of header files. Always define your headers so that it is valid to include them multiple times.
It depends on the header file; there is no language restriction on multiple includes of the same file.
Some files are designed to be included multiple times (e.g. <assert.h> can be included multiple times to turn 'on' and 'off' assert).
Many files are safe to be included multiple times because they have include guards, others are not and should be included only once in a translation unit or even a program.
include has nothing to do with the C or C++ language. It is a directive to the preprocessor to bring in a file. The preprocessor doesn't care what file is brought in and it shouldn't. It might be perfectly acceptable to do this:
void Foo::SomeFunc(int cond)
{
switch (cond) {
case kThisCase:
#include "longFirstCase.h"
break;
case kSecondCase:
#include "longSecondCase.h"
break;
case kThirdCase:
#include "longFirstCase.h"
#include "longSecondCase.h"
break;
}
}
I have seen the same file included several times as a configuration mechanism as well.
Granted, there are a number of ways to factor that example that are better, but the point is that there may be perfectly good reasons why you would want to and therefore no restriction on the use.
Probably you have some #define in DLLDefines.h around your code that prevents it from being included twice.
#ifndef DLLDEFINES_H
#define DLLDEFINES_H
// your code
#endif
As long as the multiple inclusion of header files do not violate ODR (One definition Rule) $3.2, the code is well-formed.
It's called an include guard.
#ifndef GRANDFATHER_H
#define GRANDFATHER_H
struct foo {
int member;
};
#endif
Quote from Wikipedia:
In the C and C++ programming languages, an #include guard, sometimes called a macro guard, is a particular construct used to avoid the problem of double inclusion when dealing with the #include directive. The addition of #include guards to a header file is one way to make that file idempotent.
See link above for more information.
DLLDefines.h may also have #pragma once at the
top, #pragma once ensures that file gets included only once.
I am new to this website and I am trying a simple inheritance example in C++.
I checked my code lots of times and I really see nothing wrong with it, however the compilers gives me errors:
my code:
#ifndef READWORDS_H
#define READWORDS_H
using namespace std;
#include "ReadWords.h"
/**
* ReadPunctWords inherits ReadWords, so MUST define the function filter.
* It chooses to override the default constructor.
*/
class ReadPunctWords: public ReadWords {
public:
bool filter(string word);
};
#endif
And the messages I get from the compiler:
ReadPunctWords.h:11: error: expected class-name before '{' token
ReadPunctWords.h:13: error: `string' has not been declared
ReadPunctWords.h:13: error: ISO C++ forbids declaration of `word' with no type
Tool completed with exit code 1
I am really not sure where I get it wrong as it looks just fine to me?
Thank you for any mistakes you might spot.
You need to include string:
#include <string>
That said, don't use using namespace! Especially at file-scope, and definitely not in a header file. Now any unit that includes this file is forced to succumb to everything in the std namespace.
Take that out, and qualify your names:
bool filter(std::string word);
It's arguable more readable, too. Additionally, you should take your string as a const&:
bool filter(const std::string& word);
To avoid having to copy the string unnecessarily. Lastly, your header guards seem off. Should they be changed? As of now, they seem like the same ones that would be used in your other header, which might effectively stop it from being included.
If you define READWORDS_H and then include ReadWords.h, and if that also has:
#ifndef READWORDS_H
#define READWORDS_H
Then nothing in that file will be processed. If that's the case, ReadWords as a class won't be defined, and you cannot inherit from it. Your guard should probably be:
READPUNCTWORDS_H
You need to include <string> and specify the namespace:
#include <string>
using namespace std;
Also, your include guard should probably be named READPUNCHTWORDS_H rather than READWORDS_H.
Edit: On second thought, GMan is right about not putting using namespace in a header file - qualify the string with std::string instead.
This particular form of error is often caused by a type not being defined (at least when the code looks syntactically correct), in this case probably the class ReadWords but maybe also std::string.
You need to include to get std::string, as other posters have written, but also your guard
#ifndef READWORDS_H
#define READWORDS_H
almost certainly conflicts with the guard in ReadWords.h. You need to make sure your guards are distinct in different header files otherwise you will get conflicts like this. You should change the guard to something like
#ifndef READPUNCTWORDS_H
#define READPUNCTWORDS_H
// ...
#endif
In fact, it's better to have even more verbose guards to make sure they don't conflict. We use guards of the form
#ifndef MODULE_OR_PATH_FILE_H_INCLUDED
#define MODULE_OR_PATH_FILE_H_INCLUDED
// ...
#endif
This ensures different modules or libraries with similarly named headers don't conflict, the INCLUDED thing at the end is my own particular foible that makes the guard slightly more readable.
It's also bad practice to place a "using" declaration in a header file, because it places (potentially unwanted or conflicting) symbols in the global namespace everywhere you include the header. Personally, I prefer to retain the namespace for clarity or alias it in cpp files if it's a long one, for example
namespace fs = boost::filesystem;
also looks like something wrong with ReadWords class def (message for line 11)- we need to see .h file
aha - the sentinial def you use prevents the readwords.h include being read
you need
#ifndef _READPUNCTWORDS_H
#define _READPUNCTWORDS_H
I also suspect the include guards. If they are named the same way in both header files, the result should be something like the following when ReadWords.h is pasted into ReadPunctWords.h.
#ifndef READWORDS_H // Is READWORDS_H defined? No, proceeding
#define READWORDS_H // Now it is defined
// Contents of ReadWords.h is pasted in here
#ifndef READWORDS_H // Is READWORDS_H defined? Yes, ignoring the contents of ReadWords.h (skipping til #endif)
#define READWORDS_H
class ReadWords { ... }; // This is never seen by the compiler as the preprocessor removed it
#endif
class ReadPunctWords: public ReadWords { // Error: ReadWords isn't declared...
public:
bool filter(string word);
};
#endif