Usually in C++ when I need interdependencies between classes, I use forward declarations in the header files and then include both header files in each cpp file.
How
You can utilize fine-grained headers:
// A.forward.hpp
template struct A;
// A.decl.hpp
#include "A.forward.hpp"
#include "B.forward.hpp"
template struct A
{
void RunA(B *pB);
};
// A.impl.hpp
#include "A.decl.hpp"
#include "B.hpp"
template void A< T >::
RunA(B *pB)
{
// need to do something to B here
}
// A.hpp // this one should be included by code using A
#include "A.decl.hpp"
#include "A.impl.hpp"
// B.forward.hpp
template struct B;
// B.decl.hpp
#include "B.forward.hpp"
#include "A.forward.hpp"
template struct B
{
void RunB(A *pA);
};
// B.impl.hpp
#include "B.decl.hpp"
#include "A.hpp"
template void B< T >::
RunB(A *pA)
{
// need to do something to A here
}
// B.hpp // this one should be included by code using B
#include "B.decl.hpp"
#include "B.impl.hpp"
Obviously all of these headers also need some sort of header guards that I omitted here. Important notice: .impl.hpp
headers are considered internal and should never be used by the outside code while .forward.hpp
, .decl.hpp
and .hpp
can be used anywhere.
This approach does introduce circular include dependencies, however this does not lead to problems: code structure produced by inclusion of headers ensures that code parts are included in the following order: forward declarations, class definitions, methods definitions.