It seems like you need a technique called double-dispatch
. C++
only directly supports single-dispatch - the behavior you get is only based on a single instance.
a->virtualFunction( params ); // exactly which implementation is called depends on the concrete type of a.
For double dispatch, (which does not exist), you would need something like
(a,b)->virtualFunction( params ); // where the call is based on both parameters.
There are some solutions to the problem. These require work where one type requires the knowledge of the other, but only that way round.
Consider a set of geometric shapes which we want to draw on surfaces.
class Surface;
class Drawable {
public:
virtual ~Drawable () {}
virtual void draw( Surface * ) = 0;
};
class Surface {
public:
virtual ~Surface () {}
// details ommitted.
}
class Rectangle : public Drawable {
};
class Circle : public Drawable {
}
// and some surfaces
class PrinterSurface : public Surface {
};
class PlotterSurface : public Surface {
};
The code we actually want to call, is dependent on both the surface and the shape.
To solve this, we choose one of the hierarchies which is most bounded, and tell the other hierarchy about the concrete instances of the type.
In this example, it is considered that more shapes and drawable objects will exist than technologies for rendering them.
So each drawable item will know how to draw on each of the surfaces.
class Drawable {
public:
virtual ~Drawable () {}
virtual void drawPrinter( Surface * ) = 0;
virtual void drawPlotter( Surface * ) = 0;
virtual void drawSurface( Surface * ) = 0;
};
class Surface {
public:
virtual ~Surface () {}
virtual void draw( Drawable * pDrawable ) = 0;
}
class PrinterSurface : public Surface {
void draw( Drawable * pDrawable ) {
pDrawable->drawPrinter( this );
}
};
Now a call to Surface->draw( Drawable *)
will be bounced into a concrete implementation, where each Drawable understands how to render onto a device, but the devices have no knowledge of the gamut of Drawable
s
For further reading : wikipedia : double dispatch for a more full description.
and I would recommend the design patterns book wikipedia : design patterns
The design patterns give some idea of a vocabulary of design which make asking this form of question much easier.