Generally this is implemented by having every header file pre-declare the classes that it needs before its #include
. Additionally, no code should be put in the header files. So you end up with:
class Effect;
class Player;
class GameStack;
#include <vector>
// more includes
class EffectContainer { ... }
and the equivalent in each place. Then in your .cpp
files you actually #include
the headers for the other classes. This will work if your objects don't have a circular dependency on the memory layout of the other classes. Meaning that the methods and members can only refer to the other classes by reference or by pointer (but not by value). This can get a little squirrelly if you have things like
class EffectContainer {
std::Vector<Effect> effects;
}
class Effect {
boost::shared_ptr<EffectContainer> parent;
}
as the template expansion sometimes requires full types and not merely pre-declared types. One way many libraries avoid this issue is with a pointer to private impl pattern (often referred to as a PIMPL pattern), where every class is defined as:
class FooImpl;
class Foo {
FooImpl* impl;
}
then the FooImpl
is defined entirely in the .cpp
file and your circularity issues can be ducked. This design is also valuable because it maintains binary compatibility across releases of your library. It does get a bit verbose, but nobody said C++
was a succinct language.