Reputation: 1010
I have a daunting design problem and I'm begging for some advice. To put it real short, I have two base classes A
and B
, and AImpl<T>
and BImpl<T>
inheriting from A
and B
respectively. What I need is to retrieve a (static) BImpl<T>*
from a AImpl<T>
object pointed by a polymorphic A*
pointer, but without explicitly adding something like virtual B* getB()
in A
and overriding it in AImpl<T>
because B
and BImpl<T>
already depend on A
and that would add a cyclic dependency. Both AImpl<T>
and BImpl<T>
are specialized for primitive types, std::string, T*
, etc.
Any good advice?
Edit: forward declaration is not useful here because even adding the f.d. of B in A.h and putting the method virtual B* getB() in A, being AImpl a template class, it would require a full definition of the method. getB() should return a static instance of BImpl.
To explain the problem in other terms, this is what happens: in a user cpp I include A.h and use A classes. Suppose AImpl has the method getB() defined as
const B* getB() const {
static BImpl<T> instance;
return &instance;
}
this method requires full inclusion of B.h, leading to cyclic dependency.
Edit 2, full code example I'll try to put it to a simple code example, hoping to better explain my concern.
// File A.h
struct A
{
virtual ~A();
void const A* getChild() const { /* ... */}
virtual const B* getB() const = 0;
};
template <typename T>
struct AImpl : public A
{
const B* getB() const
{
return getBImpl_of<T>();
}
};
// Specializations of AImpl<T>
template<typename T>
const A* getAImpl_of()
{
static AImpl<T> instance;
return &instance;
}
// File B.h
struct B
{
template<typename T>
static void work()
{
getBImpl_of<T>()->doWork();
}
virtual ~B();
protected:
virtual void doWork() = 0;
};
template <typename T>
struct BImpl : public B
{
protected:
void doWork()
{
const A* pA = getAImpl_of<T>();
// ... do something with pA ...
// Here is the key point:
const A* pChild = pA->getChild();
pChild->getB()->doWork();
}
};
template<typename T>
const B* getBImpl_of()
{
static BImpl<T> instance;
return &instance;
}
This is what I would like to do, but obviously including A.h in B.h and vice-versa leads to cyclic dependency. Note this is not exactly what I have, but shows the same problem. Thank you.
Upvotes: 2
Views: 173
Reputation: 64308
Forward declaration should be fine, since template methods aren't instantiated until they are used.
Try putting this at the top of your A.h:
struct B;
template <typename T> const B* getBImpl_of();
then you can include A.h from within B.h.
Upvotes: 1