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.
Related
I wanted to divide my project into smaller parts cause it started to be unreadable(1000+ lines) and i have some problem with specified .h and .cpp that need to use definitons defined in other files.
Project contains following files:
main.cpp
RPG.h and .cpp
Hero.h and .cpp
Globaldefs.h and .cpp
#ifndef Hero_h
#define Hero_h
#include "Globaldefs.h"
#include "RPG.h"
#include <vector>
using namespace std;
extern class NPC;
extern class Inventory;
class Hero
{
protected:
(...)
Inventory inventory;
(...)
public:
vector<Mob*>::iterator TryAttack(vector <Mob*>& monsters, int & number);
vector<NPC*>::iterator TryTalk(vector <NPC*>& _NPCs, int & number);
};
(...)
#endif
declaration above is from Hero.h file and compilator finds error in line Inventory inventory; (that class is outside, declared in RPG.h and defined in RPG.cpp): 'Hero::inventory' uses undefined class 'Inventory' RPG d:\programming\rpg\rpg\rpg\hero.h 23 I completely don't understand why Mob(other class from RPG.h and .cpp) work properly and NPC defined as extern(too in RPG.h) as well.
#ifndef RPG_h
#define RPG_h
#include "Globaldefs.h"
#include "Hero.h"
#include <vector>
using namespace std;
class Mob;
class NPC;
class Fight;
class Item;
extern class Hero;
(...)
class Meat : public Item
{
(...)
public:
virtual void ActivateEffect(Hero* _hero) { _hero->AddHp(15); };
};
#endif
this is RPG.h file, and there, compilator says that something went wrong in line
virtual void ActivateEffect(Hero* _hero) { _hero->AddHp(15); };
there is: use of undefined type 'Hero' RPG d:\programming\rpg\rpg\rpg\rpg.h 97 and left of '->AddHp' must point to class/struct/union/generic type RPG d:\programming\rpg\rpg\rpg\rpg.h 97
i reserched many sites, but everywhere people has problems with simple adding files to main.cpp, not making internal connections beetween files.
Inclusion guards prevent you to include RPG.h in Hero.h and vice-versa.
What you did is to forward declare Hero in RPG.h, which is good.
But then you did:
virtual void ActivateEffect(Hero* _hero) { _hero->AddHp(15); };
and the compiler needs to know the structure of Hero class to link it to AddHp method. You just cannot do that.
Do that instead (just declare the method):
virtual void ActivateEffect(Hero* _hero);
And remove the #include "Hero.h" line.
Then in the RPG.cpp file do:
#include "Hero.h"
void RPG::ActivateEffect(Hero* _hero) { _hero->AddHp(15); }
We don't see the code for the Inventory problem, but I suppose that's the same problem.
To summarize:
you can include file A.h in file B.h but in that case you cannot include file B.h in A.h
but you can forward declare class B in A.h and reference the pointer/reference on that class, as long as you don't try to use B methods in the header file.
to use B methods in A object, just include B.h in A.cpp and have access to all B method in A.cpp. Some inline methods cannot be implemented in the .h file when they use methods/members of B
You have a circular dependency between RPG.h and Hero.h, and RPG.h line 97, only the forward declaration (extern class Hero;) is visible so you can only reference pointers and references to whole Hero objects and cannot reference members of Hero.
The circular dependency may itself indicate poor design in any case.
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?
I have a circular header problem that is different from most of the ones already asked on here. I have two classes that depend on each other but not as members so don't run into the problem of the compiler not being able to calculate the class's sizes. So I'm able to use a forward-declaration to break the cycle.
However, I don't want the client to have to include both these headers to use my classes. The headers should be self-contained so the user doesn't need to be aware of this dependency. Is there some way to do this?
Edit: the tricky part is that A and B must be defined header-only.
In header A.hpp
#ifndef A_HPP
#define A_HPP
#include "B.hpp"
struct A
{
B foo() { ... }
};
#endif
In header B.hpp
#ifndef B_HPP
#define B_HPP
struct A;
struct B
{
void bar()
{
A a = A();
...
}
};
#endif
In main.cpp
#include "B.hpp"
B().bar(); // error: 'a' uses undefined class 'A'
Header B.hpp
#ifndef B_HPP
#define B_HPP
struct A;
struct B
{
void bar();
};
#endif
Source B.cpp
#include "A.hpp"
void B::bar()
{
A a;
}
EDIT. So, if you want header-only implementation, then use AndreyT solution.
If both headers contain code that requires the other type to be complete, then in general case it cannot possibly be implemented by self-contained headers.
In your specific example (which is too simple to be representative), you can simply move the definition if B::bar to A.hpp:
inline void B::bar()
{
A a = A();
...
}
But, of course, having methods of B defined in A.hpp doesn't look very elegant.
If the "inlinedness" of B::bar is important to you, the "industrial" solution would involve placing the definition of B::bar into an additional header file B_aux.hpp. When you include the headers, you should include the "aux" ones after all "normal" ones are included, i.e. in main.cpp you'd have
#include "A.hpp"
#include "B.hpp"
#include "C.hpp"
...
#include "B_aux.hpp"
...
But this is, obviously, not a "self-contained" approach.
Just add a #include "A.hpp" to the bottom of B.hpp. You'll still have a circular include, but now it won't hurt anything.
Usually circular includes are a sign that the two types are closely related, and that could mean that they are a single component. If that is the case, then just merge the two headers into a single header for the component, with the type declarations first and the member function definitions at the end, when both types have been fully defined.
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.
I admit I'm a bit naive when it comes to includes. My understanding is that if you use it in your class you either need to include it or forward declare it. But then I was going through some code and I saw this:
// file: A.cpp
#include "Helper.h"
#include "B.h"
#include "C.h"
#include "A.h"
// ...
// file: A.h
B b;
C c;
// ...
// file: B.h
Helper h;
// ...
// file: C.h
Helper h;
// ...
Can someone explain to me why B and C does not need to include Helper? Also, what are the advantages/disadvantages to organizing includes this way? (Besides the obvious less typing.)
Thanks.
When you #include some header (or other) file into a .cpp file, that #include statement is simply replaced by the content of the header file. For example:
//header.h
int i;
float f;
// file.cpp
#include"header.h"
int main()
{}
After preprocessing stage, file.cpp will look like,
int i;
float f;
int main()
{}
Can see this in g++ using g++ -E file.cpp > TEMP, which shows you just the preprocessed files.
In your present question context, you must have #include helper.h in/before B.h and C.h as they appear before and you declare an object of those types.
Also, it's not good practice to rely on the arrangement of header files to get the code working, because once you alter arrangement little, the whole hierarchy collapses with several compilation errors.
Instead #include everything in the file if you are using it and you can use the #ifndef guards to avoid multiple inclusion:
//helper.h
#ifndef HELPER_H
#define HELPER_H
// content of helper file
#endif
If the class definitions for B and C don't actually refer to any of the members of the Helper class, then the compiler doesn't need to see the full definition of the Helper class in their header files. A forward declaration of the Helper class is sufficient.
For example, if the definition of the B class only uses pointers or references to Helper, then a forward reference is recommended :
class Helper;
class B {
// <SNIP>
Helper* helper;
// <SNIP>
void help(const Helper& helper);
// <SNIP>
};
If the definition of the B class uses an instance of the Helper class (ie. it needs to know the size of the Helper instance), or otherwise refers to the definition of the Helper class (in template functions eg.), then you need to make the full definition of the Helper class visible (most likely by including the header file that defines the Helper class) :
#include "helper.h"
class B {
// <SNIP>
Helper helper;
// <SNIP>
void help(Helper helper);
// <SNIP>
};
The rule of when to use includes versus forward declarations is relatively straightforward : use forward declarations when you can, and includes when you have to.
The advantage of this is clear : the less includes you have, the less dependencies there are between header files (and the more you'll speed up compilation).
Think of #include as literally including the text of the other file in this one - it's exactly the same as if you had copied it in. So in this case, the reason B and C don't need to include Helper is because you've included it in the same "compilation unit", which is what the combination of a .cpp file and all its includes is called.
With templates, a forward declaration might be enough even if the members of the forward declared type are referred to in the header file.
For example, the boost::shared_ptr<T> implementation only forward declares boost::weak_ptr<T> even though it is used in two constructors. Here is a code snipped from http://www.boost.org/doc/libs/1_47_0/boost/smart_ptr/shared_ptr.hpp:
namespace boost
{
// ...
template<class T> class weak_ptr;
// ...
template<class T> class shared_ptr
{
// ...
public:
// ...
template<class Y>
explicit shared_ptr(weak_ptr<Y> const & r): pn(r.pn) // may throw
{
// it is now safe to copy r.px, as pn(r.pn) did not throw
px = r.px;
}
template<class Y>
shared_ptr( weak_ptr<Y> const & r, boost::detail::sp_nothrow_tag ): px( 0 ), pn( r.pn, boost::detail::sp_nothrow_tag() ) // never throws
{
if( !pn.empty() )
{
px = r.px;
}
}
In this case, a forward declaration of boost::weak_ptr<T> is enough since the two constructors do not get instantiated unless the definition for the forward declared boost::weak_ptr<T> has been included in the compilation unit that is using those constructors.