I have a .h file which contains several class definitions. I'd like to use C++'s include guards in this file; however, I was wondering which way of using the include guards is considered proper/correct?
One guard protecting everything
#ifndef FOO_BAR
#define FOO_BAR
class Foo
{
};
class Bar
{
};
#endif
or multiple separate guards.
#ifndef FOO
#define FOO
class Foo
{
};
#endif
#ifndef BAR
#define BAR
class Bar
{
};
#endif
They are include guards, preventing double inclusion of files. So they should be defined once per file, not per class or function or whatever.
Have you considered to use #pragma once ? Most modern compilers support it.
Is #pragma once a safe include guard?
Related
I have an interface ver as
// ver.h
class ver
{
public:
virtual void func()=0;
};
Then ver1 and ver2 implement this interface. ver1 and ver2 differ in the sense they include header test\header.h and test2\header.h. Now test\header.h and test2\header.h are not under my control and are mostly similar except for a function pointer which is the reason for having ver1 and ver2
// test\header.h
#ifndef header
#define header
typedef void
(*FuncPoint)(
struct_type_a
);
#endif
and
// test2\header.h
#ifndef header
#define header
typedef void
(*FuncPoint)(
struct_type_b
);
#endif
Now the implementations
//ver1.h
#include "test\header.h"
class ver1:public ver
{
public:
FuncPoint f;
};
and
//ver2.h
#include "test2\header.h"
class ver2:public ver
{
public:
FuncPoint f;
};
and ver1.cpp and ver2.cpp will be using the respective f
Now the polymorphic behavior comes into play here
//something.cpp
#include "ver.h"
#include "ver1.h"
#include "ver2.h"
ver* somefunc()
{
if (some_condition)
return new ver1();
else
return new ver2();
}
Since something.cpp includes both ver1.h and ver2.h, first test\header1.h gets included and because of the include guards, test\header2.h is not included and hence there is no FuncPoint defined for class ver2 and something.cpp fails to compile.
On the other hand ver1.cpp and ver2.cpp gets compiled successfully since there is only one header.h included.
I could do a #undef header after including ver1.h in something.cpp but that would give redefinition error for other things which are same in test\header.h1 and tes\header2.h.
A simple fix would be to not have FuncPoint f as global variables instead of member variables, this way i won't have to include test\header.h in ver1.h but instead in ver1.cpp.
Is there some other better way to fix this?
EDIT:
I could forward declare struct_type_a and struct_type_b in something.cpp and avoid including ver1.h and ver2.h in something.cpp. But class ver1 and ver2 use other things(to declare members) from test\header.h as well(which are same in both versions).
Don't include header.h in ver1.h or ver2.h but in the respective .cpp files: FuncPoint is a pointer so you can use forward declarations. Since ver1.h and ver2.h will both be included you will need to rename it however where exposed (in the .cpp files you will be able to use the original FuncPoint too, since you include only one definition of it there):
//ver1.h
#include "ver.h"
struct struct_type_a;
typedef void (*FuncPoint_a)(struct_type_a);
class ver1 : public ver
{
public:
FuncPoint_a f;
static ver1 *create();
};
Also the creation of the polymorphic objects must be demanded to methods implemented in the .cpp files, in the create() static method.
Following your code it would become:
//something.cpp
#include "ver.h"
#include "ver1.h"
#include "ver2.h"
ver* somefunc()
{
if (some_condition)
return ver1::create();
else
return ver2::create();
}
In this way the two colliding headers will never be included in the same file.
I've added the inclusion of ver.h in ver1.h (and ver2.h) because this is the source using it. Including it in something.cpp only is not correct (ver1 and ver2 need it) - but not related to the current problem.
Why declare the class that you included as a header file?
#include "TreeCallObj.h"
#include "TreeDevObj.h"
#include "TreeDevCallObj.h"
class TreeCallObj; //what is the purpose of this line ?
class TreeDevObj; //what is the purpose of this line ?
class TreeDevCallObj; //what is the purpose of this line ?
class Apple
{
public:
...
private:
...
}
Consider this:
//a.h
#ifndef A_H
#define A_H
#include "b.h"
class A
{
B* b;
};
#endif
//b.h
#ifndef B_H
#define B_H
#include "a.h"
class B
{
A* a;
};
#endif
Now you try to include one of the files in a different one, say you #include "a.h".
The compiler will parse it as:
#ifndef A_H
#define A_H
fine - A_H isn't defined
#include "b.h"
try to paste the contents:
#ifndef B_H
#define B_H
ok, since B_H isn't defined
#include "a.h"
this will not define A, because A_H is defined. So next, we have
class B
{
A* a;
};
which will lead to an error, because A wasn't defined or declared before the use.
The forward declaration fixes this.
Of course, the best solution to this is to not include at all (unless you absolutely have to).
What is the purpose of this line?
Ideally nothing. It's superfluous.
However, as #Luchian Grigore pointed out, there may be such a badly-designed code that due to the incorrect use of include guards and cross-includes, the forward declarations may be necessary.
If in files there is definition of classes, so, forward declaration is unnecessary in normal cases.
No reason at all. You need to do one or the other, depending on the situation, but not both.
As it stands, there's no need.
However, this may have evolved historically: At some point, an incomplete type may have been enough:
class Foo;
struct Gizmo
{
void f(Foo);
};
Then, at a later point, the author decided she needed the complete type:
#include "Foo.hpp"
class Foo;
struct Gizmo
{
void f(Foo);
Foo x;
};
The original code may just have been amended with the now-necessary header inclusion...
I would guess there's some history to this. Orginally the coder tried not to include the header files and used forward declarations instead. Then as the code expanded they found they needed the header files after all, but didn't bother to deleted the forward declarations.
As others have said there's no purpose to having a forward declaration after the class declaration.
I notice that your header does not have guards against multiple inclusion. Also it is possible that some of the included other headers (headers usually have such guards) included that header back. As result it did not compile. So someone added forward declarations to fix the wrong bug.
If your header files are correct i see no point in declaring because they should already declared in header
I have a header file called custom_types.h that was working fine until now. I have a few enums declared in it and there is no implementation file with the same name.
These are the two declarations in the file:
enum playback_type {
NOTE_PB,
SONG_PB
};
enum note_name {
C_REG = 1,
C_SHARP = 2,
D_REG = 3
};
Now for some reason I'm getting conflicting declaration errors (full size here):
You guys have any idea why this is happening? I don't understand how a single definition can be conflicting.
Use guards:
//custom_types.h
#ifndef custom_types_h //this is called guard!
#define custom_types_h
enum playback_type {
NOTE_PB,
SONG_PB
};
enum note_name {
C_REG = 1,
C_SHARP = 2,
D_REG = 3
};
#endif //dont forget this line!
Such guards ensure that the content of the header file will be included once in one translation unit (TU).
If your compiler supports (modern compilers support this), you could use #pragma once as:
//custom_types.h
#pragma once //it ensures that the content of this header will be
//included once in one translation unit
enum playback_type {
NOTE_PB,
SONG_PB
};
enum note_name {
C_REG = 1,
C_SHARP = 2,
D_REG = 3
};
Since headers are full of declarations, you must make sure the compiler doesn't read them twice. Once solution would be to make sure each header is included (directly or through another header) only once. This is not so easy.
The common solution is to add guards:
#ifndef SOME_CONSTANT_THAT_WONT_GET_MISTAKEN
#define SOME_CONSTANT_THAT_WONT_GET_MISTAKEN
... header contents ...
#endif
If this header gets included multiple times, the compiler will see both copies, but will discard the second one, since that SOME_CONSTANT... is already defined. That is, this:
#include "your_file.h"
...
#include "your_file.h"
will become:
#ifndef SOME_CONSTANT_THAT_WONT_GET_MISTAKEN // not defined
#define SOME_CONSTANT_THAT_WONT_GET_MISTAKEN // define it
... header contents ... // read these
#endif
...
#ifndef SOME_CONSTANT_THAT_WONT_GET_MISTAKEN // already defined
#define SOME_CONSTANT_THAT_WONT_GET_MISTAKEN // skip
... header contents ... // skip
#endif
most likely you are including the file more than once, that is the same #include in several other .h or .c/.cpp
The easiest way to solve this is to have at the beginning of every .h file a #ifndef that avoids redefinition when the file has already been included through another inclusion path.
I have a number of classes and they are quite close to each other like
class A
{
//code
};
class B
{
A* field;
//code
};
class C: public B
{
//code
};
And so on.
And I want to place them in a separate headers (A.h, B.h...) but to avoid adding every one of this header to projects I need a header like myLib.h, that will be just one needed header to include all the classes that I have wrote. Ho do I achieve it?
Also I think not to use #pragma once; and to make it working
#ifndef _MY_LIB_H
#define _MY_LIB_H
#endif
Where should I place it? In every header?
I've tried doing it like
class A;
class B;
...
in myLib.h
but then adding myLib.h to main.cpp is not enough to use A or B objects there. Also, in B.h that
#inlude myLib.h
void someMethod()
{
//field is instance of A
this.field.otherMethod();
}
causes an error because methods of A are declared in A.h, not in myLib.h.
Sorry for long and tangled question.
You should use a separate include guard in each of A.h, B.h, C.h:
// Note: not a good name for a guard macro (too short)
#ifndef _A_H
#define _A_H
// definition of A
#endif
And then MyLib.h becomes simply:
#include<A.h>
#include<B.h>
#include<C.h>
Of course each of your headers should manually include as many of the others as required so that it can stand alone (e.g. C.h would need to include B.h so that the code compiles if someone includes C.h directly).
In some cases you will not need to have one header include another because a forward declaration is enough -- for example in B.h, where an A* member is declared:
#ifndef _B_H
#define _B_H
class A;
class B
{
A* field;
};
#endif
Besides using the pattern
#ifndef _A_H
#define _A_H
... Stuffs
#endif
in each header, I always add
#ifndef _A_H
#include <A.h>
#endif
#ifndef _B_H
#include <B.h>
#endif
....
to other headers, like myLib.h. This considerably improves the speed of compilation because compiler does not need to load and scan the low level headers if they are already scanned.
I do not add this to my cpp files, because the number of headers in cpp is typically reasonable, while it mich more difficult to track relations between headers.
#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.