Matching an overloaded function to its polymorphic argument - c++

Okay, the title is a mouthful and I think that's probably why it has been tough to find an answer through google or this site. It might just be that I don't know how to express the problem correctly but here goes:
I have a series of methods in a SimpleOpenGLRenderer class that all take a single argument that extends the Model class. So the idea is that depending on the type of model, the renderer will invoke the correct method that knows how to render it. Here is a simplified executable example based on the problem:
#include <stdio.h>
class Model {};
class Cube : public Model {};
class Sphere : public Model {};
class Renderer
{
public:
virtual void renderModel(const Model& model) = 0;
};
class SimpleOpenGLRenderer
{
public:
void renderModel(const Cube& model)
{
printf("Render the cube.\n");
}
void renderModel(const Model& model)
{
printf("Throw an exception, my renderer does not support the model type you have provided.\n");
}
void renderModel(const Sphere& model)
{
printf("Render the sphere.\n");
}
};
int
main(int argc, char** argv)
{
Cube cube;
Model& model = cube;
SimpleOpenGLRenderer renderer;
renderer.renderModel(cube);
renderer.renderModel(model);
}
The output from the example is:
Render the cube.
Throw an exception, my renderer does not support the model type you have provided.
It may seem obvious to a more seasoned C++ developer that this does not work as planned but it just doesn't make sense to me. At runtime I will not know the exact type of the Model passed to the renderer (hence the attempted overloading to resolve it). Coming from a Java background, I have used this technique before and in Java the method called will be that which best matches the runtime type of the argument. In C++ it seems to match to the compile-time type of the reference, even if that reference may end up being to a subclass that - to my mind - better matches another function.
Up until now I had taken this runtime type matching for granted. Does it simply not exist in C++ or am I going about this the wrong way? Should I be doing something differently in C++ to achieve it?
Thanks,
Gary.

Overloads in C++ are resolved at compile time, based on the static type of the argument.
There's a technique known as "double-dispatch" that might be of use:
class Model {
virtual void dispatchRender(Renderer &r) const = 0;
};
class Cube : public Model {
virtual void dispatchRender(Renderer &r) const {
r.renderModel(*this); // type of "this" is const Cube*
};
int main() {
Cube cube;
Model &model = cube;
SimpleOpenGLRenderer renderer;
cube.dispatchRender(renderer);
}
Note that the Renderer base class needs to contain all the overloads that SimpleOpenGLRenderer currently does. If you want it to be specific to SimpleOpenGLRenderer what overloads exist then you could put a Simple-specific dispatch function in Model, or you could ignore this technique and instead use dynamic_cast repeatedly in SimpleOpenGLRenderer::renderModel to test the type.

In your code, the function overloads are resolved based on the static type of the argument.
What you need probably is double-dispatch mechanism which is very close to Visitor pattern. Read these:
Double Dispatch
Visitor Pattern

For "runtime overloading" based on the dynamic type it is possible to use visitor pattern.

Your code is a good candidate of runtime type matching, if you use it. Here you are receiving Cube into Model& and passing the same simply to the renderModel(). Till now you haven't given chance to the compiler to use the runtime type. But rather relying on the static type of the object.
In 2 ways you could have used the runtime type checking. One is using dynamic_cast<> and other one is providing the interface method in Model. i.e.
class Model {
virtual void print () { printf("throw..."); } // provide an interface method
};
class Cube : public Model {
virtual void print () { print("Render cube\n"; } // implement it
};
class Sphere : public Model {
virtual void print () { print("Render sphere\n"; } // implement it
};
class SimpleOpenGLRenderer
{
public:
void renderModel(const Model& model)
{
model.print();
}
};

In C++ the resolution of which overload to call, is done at compile time.
To make the effective implementation depend on the polymorphic argument type, you need to consult that argument, i.e., call a virtual method on the argument.
I think the cleanest way to do that here is what's called the visitor pattern. Your SimpleOpenGLRenderer can call a method model.renderOn( *this ). Then Model::renderOn is either a set of overloads, one for each possible type of renderer, or it is a single virtual method that uses dynamic_cast to discover the type of renderer. In any way, it then calls back on the renderer, but now that call knows what type of renderer it is and what type itself is, and can also call a very specific rendering method, like, SimpleOpenGLRenderer::renderCube.
Cheers,

The other solutions here will do exactly what you want. But in my opinion at the cost of complexity. If your problem is exactly as described, I would suggest to change the architecture of your solution instead. Aren't the renderer trying to do the job of the model? What I see is a kind a overload generated switch sentence.
How about making the models rendering themself, perhaps by using some class offering more primitive drawing methods:
class Cube : public Model {
render(RenderTool& tool) {
tool.renderCube(); //or even more low level
}
};
class SimpleOpenGLRenderer {
public:
RenderModel(Model& model) {
model.render(renderTool);
}
private:
SomeOpenGLRenderingTool renderTool;
};

Related

Dynamically construct function

I fear something like this is answered somewhere on this site, but I can't find it because I don't even know how to formulate the question. So here's the problem:
I have a voxel drowing function. First I calculate offsets, angles and stuff and after I do drowing. But I make few versions of every function because sometimes I want to copy pixel, sometimes blit, sometimes blit 3*3 square for every pixel for smoothing effect, sometimes just copy pixel to n*n pixels on the screen if object is resized. And there's tons of versions for that small part in the center of a function.
What can I do instead of writing 10 of same functions which differ only by central part of code? For performance reasons, passing a function pointer as an argument is not an option. I'm not sure making them inline will do the trick, because arguments I send differ: sometimes I calculate volume(Z value), sometimes I know pixels are drawn from bottom to top.
I assume there's some way of doing this stuff in C++ everybody knows about.
Please tell me what I need to learn to do this. Thanks.
The traditional OO approaches to this are the template method pattern and the strategy pattern.
Template Method
The first is an extension of the technique described in Vincenzo's answer: instead of writing a simple non-virtual wrapper, you write a non-virtual function containing the whole algorithm. Those parts that might vary, are virtual function calls.
The specific arguments needed for a given implementation, are stored in the derived class object that provides that implementation.
eg.
class VoxelDrawer {
protected:
virtual void copy(Coord from, Coord to) = 0;
// any other functions you might want to change
public:
virtual ~VoxelDrawer() {}
void draw(arg) {
for (;;) {
// implement full algorithm
copy(a,b);
}
}
};
class SmoothedVoxelDrawer: public VoxelDrawer {
int radius; // algorithm-specific argument
void copy(Coord from, Coord to) {
blit(from.dx(-radius).dy(-radius),
to.dx(-radius).dy(-radius),
2*radius, 2*radius);
}
public:
SmoothedVoxelDrawer(int r) : radius(r) {}
};
Strategy
This is similar but instead of using inheritance, you pass a polymorphic Copier object as an argument to your function. Its more flexible in that it decouples your various copying strategies from the specific function, and you can re-use your copying strategies in other functions.
struct VoxelCopier {
virtual void operator()(Coord from, Coord to) = 0;
};
struct SmoothedVoxelCopier: public VoxelCopier {
// etc. as for SmoothedVoxelDrawer
};
void draw_voxels(arguments, VoxelCopier &copy) {
for (;;) {
// implement full algorithm
copy(a,b);
}
}
Although tidier than passing in a function pointer, neither the template method nor the strategy are likely to have better performance than just passing a function pointer: runtime polymorphism is still an indirect function call.
Policy
The modern C++ equivalent of the strategy pattern is the policy pattern. This simply replaces run-time polymorphism with compile-time polymorphism to avoid the indirect function call and enable inlining
// you don't need a common base class for policies,
// since templates use duck typing
struct SmoothedVoxelCopier {
int radius;
void copy(Coord from, Coord to) { ... }
};
template <typename CopyPolicy>
void draw_voxels(arguments, CopyPolicy cp) {
for (;;) {
// implement full algorithm
cp.copy(a,b);
}
}
Because of type deduction, you can simply call
draw_voxels(arguments, SmoothedVoxelCopier(radius));
draw_voxels(arguments, OtherVoxelCopier(whatever));
NB. I've been slightly inconsistent here: I used operator() to make my strategy call look like a regular function, but a normal method for my policy. So long as you choose one and stick with it, this is just a matter of taste.
CRTP Template Method
There's one final mechanism, which is the compile-time polymorphism version of the template method, and uses the Curiously Recurring Template Pattern.
template <typename Impl>
class VoxelDrawerBase {
protected:
Impl& impl() { return *static_cast<Impl*>(this); }
void copy(Coord from, Coord to) {...}
// *optional* default implementation, is *not* virtual
public:
void draw(arg) {
for (;;) {
// implement full algorithm
impl().copy(a,b);
}
}
};
class SmoothedVoxelDrawer: public VoxelDrawerBase<SmoothedVoxelDrawer> {
int radius; // algorithm-specific argument
void copy(Coord from, Coord to) {
blit(from.dx(-radius).dy(-radius),
to.dx(-radius).dy(-radius),
2*radius, 2*radius);
}
public:
SmoothedVoxelDrawer(int r) : radius(r) {}
};
Summary
In general I'd prefer the strategy/policy patterns for their lower coupling and better reuse, and choose the template method pattern only where the top-level algorithm you're parameterizing is genuinely set in stone (ie, when you're either refactoring existing code or are really sure of your analysis of the points of variation) and reuse is genuinely not an issue.
It's also really painful to use the template method if there is more than one axis of variation (that is, you have multiple methods like copy, and want to vary their implementations independently). You either end up with code duplication or mixin inheritance.
I suggest using the NVI idiom.
You have your public method which calls a private function that implements the logic that must differ from case to case.
Derived classes will have to provide an implementation of that private function that specializes them for their particular task.
Example:
class A {
public:
void do_base() {
// [pre]
specialized_do();
// [post]
}
private:
virtual void specialized_do() = 0;
};
class B : public A {
private:
void specialized_do() {
// [implementation]
}
};
The advantage is that you can keep a common implementation in the base class and detail it as required for any subclass (which just need to reimplement the specialized_do method).
The disadvantage is that you need a different type for each implementation, but if your use case is drawing different UI elements, this is the way to go.
You could simply use the strategy pattern
So, instead of something like
void do_something_one_way(...)
{
//blah
//blah
//blah
one_way();
//blah
//blah
}
void do_something_another_way(...)
{
//blah
//blah
//blah
another_way();
//blah
//blah
}
You will have
void do_something(...)
{
//blah
//blah
//blah
any_which_way();
//blah
//blah
}
any_which_way could be a lambda, a functor, a virtual member function of a strategy class passed in. There are many options.
Are you sure that
"passing a function pointer as an argument is not an option"
Does it really slow it down?
You could use higher order functions, if your 'central part' can be parameterized nicely.
Here is a simple example of a function that returns a function which adds n to its argument:
#include <iostream>
#include<functional>
std::function<int(int)> n_adder(int n)
{
return [=](int x){return x+n;};
}
int main()
{
auto add_one = n_adder(1);
std::cout<<add_one(5);
}
You can use either Template Method pattern or Strategy pattern.
Usually Template method pattern is used in white-box frameworks, when you need to know about the internal structure of a framework to correctly subclass a class.
Strategy pattern is usually used in black-box frameworks, when you should not know about the implementation of the framework, since you only need to understand the contract of the methods you should implement.
For performance reasons, passing a function pointer as an argument is not an option.
Are you sure that passing one additional parameter and will cause performance problems? In this case you may have similar performance penalties if you use OOP techniques, like Template method or Strategy. But it is usually necessary to use profilier to determine what is the source of the performance degradation. Virtual calls, passing additional parameters, calling function through a pointer are usually very cheap, comparing to complex algorithms. You may find that these techniques consumes insignificant percent of CPU resources comparing to other code.
I'm not sure making them inline will do the trick, because arguments I send differ: sometimes I calculate volume(Z value), sometimes I know pixels are drawn from bottom to top.
You could pass all the parameter required for drawing in all cases. Alternatively if use Tempate method pattern a base class could provide methods that can return the data that could be required for drawing in different cases. In Strategy pattern, you could pass an instance of an object that could provide this kind of data to a Strategy implementation.

C++: How to get decoupled polymorphic behavior

In a Qt project in C++, I am writing an interface for dynamically loaded plugins using QtPlugin. This interface should allow plugins to register their different parameters, and while a plugin is loaded the main program should display appropriate GUI controls representing each parameter. For instance, a parameter could be an int between 0 and 20 a represented by a QLabel and a QSlider in a box, or a color value represented by a QColorDialog.
Here's the catch: I tried a standard OOP approach (?), having each parameter type inherit an abstract class and creating the GUI representation by implementing a virtual function. This caused a lot of Qt GUI headers to get linked into each plugin file, increasing its size from ~20 KB to ~50 KB.
This isn't about saving those kilobytes but about gaining a better understanding of OOP. I thought about this and tried to find suitable design patterns, then I googled "decoupled polymorphism", "external polymorphism" et c and came across a page that said that this is possible but generally you don't want to go there because it breaks OOP.
So is that it? Either I hide GUI code from the plugin interface and identify each type with an enum or something, and "break OOP", or the class is entirely reponsible for itself but also completely coupled internally?
What solutions would you recommend, if each parameter type consists of a data model, persistence, and GUI controls with signals? What goes where?
EDIT: In other words I'm wondering if the plugins can be pure data and algorithms, unaware of how data controls are created in Qt and independent of Qt GUI headers. It might use Q_OBJECT for signals though.
I'd suggest letting the plugin worry about the types of its arguments, and have a separate component which knows how to map each type onto a GUI control.
This is almost a straight model/view decomposition, so seems like a well-understood idiom.
Now, your type model can be enumerated, or you can use the arguably more OO Visitor pattern, but you're still essentially coming up with a fixed and not-really-extensible type system ahead of time. Is that adequate?
You'll probably end up with some type that knows both the specific derived type of a given argument, and the details of how to render it in Qt. This would handle the Qt signals, and pass values back to the argument.
... Through attempting a dynamic_cast or reading some kind of identification code such as an enum, I'm thinking. I still don't see how the Visitor DP could be used instead of these ...
The Visitor pattern is specifically used to avoid dynamic_cast, so I'm not sure what the confusion is here. Admittedly there's a post-hoc version which does use dynamic_cast, but that's hidden away in the implementation and isn't the usual case anyway.
So, for a concrete example, let's create a model with a couple of argument types:
struct ArgumentHandler; // visitor
class Argument { // base class for visitable concrete types
public:
virtual void visit(ArgumentHandler&) = 0;
};
// sample concrete types
class IntegerArgument: public Argument {
int value_;
public:
IntegerArgument(int value = 0) : value_(value) {}
void set(int v) { value_ = v; }
int get() const { return value_; }
virtual void visit(ArgumentHandler&);
};
class BoundedIntegerArgument: public IntegerArgument
{
int min_, max_;
public:
virtual void visit(ArgumentHandler&);
// etc...
};
Now we have some concrete types for it to visit, we can write the abstract visitor
struct ArgumentHandler {
virtual ~ArgumentHandler() {}
virtual void handleInteger(IntegerArgument&);
virtual void handleBoundedInteger(BoundedIntegerArgument&);
// ...
};
and our concrete types implement visitation like so:
void IntegerArgument::visit(ArgumentHandler& handler) {
hander.handleInteger(*this);
}
void BoundedIntegerArgument::visit(ArgumentHandler& handler) {
hander.handleBoundedInteger(*this);
}
Now, we can write an abstract plugin only in terms of the data model types - it doesn't need to know anything about the GUI toolkit. Let's say we just provide a way to query its arguments for now (note that each concrete subtype should have set/get methods)
class PluginBase
{
public:
virtual int arg_count() const = 0;
virtual Argument& arg(int n) = 0;
};
Finally, we can sketch a View that knows how to interrogate an abstract plugin for its arguments, how to display each concrete argument type, and how handle inputs:
// concrete renderer
class QtView: public ArgumentHandler
{
struct Control {};
struct IntegerSpinBox: public Control {
QSpinBox control_;
IntegerArgument &model_;
};
struct IntegerSlider: public Control {
QSlider control_;
BoundedIntegerArgument &model_;
};
std::vector<std::unique_ptr<Control>> controls_;
public:
// these overloads know how to render each argument type
virtual void handleInteger(IntegerArgument &arg) {
controls_.push_back(new IntegerSpinBox(arg));
}
virtual void handleBoundedInteger(BoundedIntegerArgument &arg) {
controls_.push_back(new IntegerSlider(arg));
}
// and this is how we invoke them:
explicit QtView(PluginBase &plugin) {
for (int i=0; i < plugin.arg_count(); ++i) {
plugin.arg(i).visit(*this);
}
}
};
I've omitted all the virtual destructors, the Qt signal handling, and lots more. But, hopefully you can see how a QtView::IntegerSpinBox object could handle the valueChanged signal from its captive spinbox widget, and call model_.set() to push that back to the plugin.
You can send message of any type, to anywhere and catch it on the other side with anything with templatious virtual packs which were made exactly for loose-coupling-with-anything purpose.
If I understood you correctly, you should rethink the behaviour. Instead of having the module registering everything (which can be really a lot) in the main app, you could create a base class for a module specific renderer, and a factory in each module, that instantiates the concrete renderer for the module. You then can ask the module to render the information you are providing to the module.

a class inherited from two class, with the same function prototype, conflict with each other

I am working on a Ray Tracing task, here is the problematic source:
class Geometry
{
public:
virtual RayTask *intersectionTest(const Ray &ray) = 0;
};
class Sphere : public Geometry
{
public:
RayTask *intersectionTest(const Ray &ray);
};
class BoundingVolume
{
public:
virtual bool intersectionTest(const Ray &ray) = 0;
};
class BoundingSphere : public Sphere, BoundingVolume
{
public:
bool intersectionTest(const Ray &ray) // I want this to be inherited from BoundingVolume
{
return Sphere::intersectionTest(ray) != NULL; // use method in Sphere
}
};
source above can not compile, error information:
error: conflicting return type specified for ‘virtual bool BoundingSphere::intersectionTest(const Ray&)’
error: overriding ‘virtual RayTask Sphere::intersectionTest(const Ray&)
I want to implement BoundingSphere::intersectionTest using method in Sphere, so I need to inherit from both BoundingVolume and Sphere. but due to inherit functions that has the same parameter list with different return type, things messed up...
I do not want to duplicate codes with the same functionality...
could any one give me a solution?...
The compiler is attempting to override two virtual methods with different return types, which isn't allowed: how would the compiler know how much memory to allocate for a function call if it doesn't know what the return type will be? The two methods cannot have the same names; try changing one to a more suitable meaning.
If you feel that these names best represent the meanings of the actions they both provide (which I'm not sure of), I would also suggest that you consider your hierarchies carefully. Is a spherical BoundingVolume really a Sphere? Perhaps not: it's implemented in terms of Sphere (private inheritance, doesn't solve your problem), or it has a Sphere (composition, would solve your problem in this simple case). The latter case, though, might present problems for move complex classes, where you want a BoundingSphere to have all the methods of Sphere. Or, perhaps, do you need to differentiate between BoundingVolumes and normal Geometrys?
Another solution to the problem would be to use non-member functions for one of these hierarchies, with Koenig lookup (the type of the argument) calling the proper version. I can't say without really knowing what your hierarchies look like. But do consider your design: if you have the same-named operation giving you back completely different semantic results, is the operation properly named/designed?

redefining or adding a classes member function dynamically/ during execution

Hey i'm trying to make a very simple GUI using SFML, and i want to be able to attach a function to my Button class in the constructor, as so the user can define what happens when the button is pressed.
I've worked a little before with GLUT and noticed these declerations:
glutReshapeFunc(Resize);
glutDisplayFunc(Draw);
Which apparently define what function should be called when the window is resized or displayed. I want something exactly like this for my button so upon construction you can define what function should be called. I want to be able to pass a function name just like glut, not having define a new class wich overides a virtual functin.
I also doubt it's possible however to pass parameters for these
called functions, as you never know what or how many there would be.
Am i right?
So anyway..... How do i accomplish this or something like it?? Thanks!
You can store a callback using e.g. std::function (for C++0x; boost::function is also available and has a similar interface).
#include <functional>
class Button {
public:
template<typename T>
explicit
Button(T const& t): callback(t) {}
void
press()
{
callback();
}
private:
std::function<void()> callback;
};
// example use with a lambda
Button b([] { do_stuff(); });
b.press(); // will call do_stuff
In C++ it's better to use virtual function approach to address such kind of problems. That's more maintainable at long run.
You can choose to redesign a little bit to your code, where you can have a common handle to various subclasses. Now based on subclass chosen you can call a particular function. For example:
class Shape
{
public:
virtual void Resize () = 0;
virtual void Draw () = 0;
};
class Triangle : public Shape
{
public:
// implement above to functions
};
class Square : public Shape
{
public:
// implement above to functions
};
Now, just pass the handle of Shape* wherever you want and call the above abstract methods;
void foo(Shape *p)
{
p->Resize();
}
(Rewrote everything), I had misread the question.
You seem to be wanting to pass plain old function pointers around to other functions. All you need to do is just pass the name of the function you want, but do so inside an if (or something like that) so the function passed is actualy what you want:
if(i am feeling lucky today){
glutDisplayFunc(DrawMyLuckyShape);
}else{
glutDisplayFunc(DrawAFoo);
}
The bad news is that since C is a nasty language you can't set up to pass extra parameters to your functions (ie, use closures). Therefore, you need to rely on a) the functions being passed some parameter quen being called or b) the functions looking at some global state.

C++ inheritance question

I have the following problem in application architecture and am willing to solve it (sorry for a lot of text).
I am building a game engine prototype and I have base abstract class AbstractRenderer (I will use C++ syntax, but still the problem is general).
Assume there are some derived implementations of this renderer, let's say DirectxRenderer and OpenglRenderer.
Now, let's say that only one of these renderers (let's stick to DirectX-based) has a member called IDirect3D9Device* m_device; Obviously at this point everything is fine - m_device is used internally in DirectxRenderer and shouldn't be exposed in the abstract AbstractRenderer superclass.
I also add some abstract rendering interface, for instance IRenderable. It means simply one pure virtual method virtual void Render(AbstractRenderer* renderer) const = 0;
And this is the place where some problems start. Assume I am modelling some scene, so, this scene will probably have some geometrical objects in it.
I create abstract superclass AbstractGeometricalObject and derived DirectX-based implementation DirectxGeometricalObject. The second one would be responsible for storing pointers to DirectX-specific vertex & index buffers.
Now - the problem.
AbstractGeometricalObject should obviously derive the IRenderable interface, because it's renderable in logical terms.
If I derive my DirectxGeometricalObject from AbstractGeometricalObject, the first one should have virtual void Render(AbstractRenderer* renderer) const { ... } method in it, and that Abstract... stuff brings some troubles.
See the code for better explanation:
And for now my classes look the following way:
class AbstractGeometricalObject : public IRenderable {
virtual void Render(AbstractRenderer* renderer) const { ... }
};
class DirectxGeometricalObject : public AbstractGeometricalObject {
virtual void Render(AbstractRenderer* renderer) const {
// I think it's ok to assume that in 99 / 100 cases the renderer
// would be a valid DirectxRenderer object
// Assume that rendering a DirectxGeometricalObject requires
// the renderer to be a DirectxRenderer, but not an AbstractRenderer
// (it could utilize some DX-specific settings, class members, etc
// This means that I would have to ***downcast*** here and this seems really
// bad to me, because it means that this architecture sucks
renderer = dynamic_cast<DirectxRenderer*>(renderer);
// Use the DirectX capabilities, that's can't be taken out
// to the AbstractRenderer superclass
renderer.DirectxSpecificFoo(...);
}
I know I'm probably worrying too much, but this downcast in such a simple case means that I could be forced to make lots of downcasts if my application grows.
Definitely, I would like to avoid this, so please, could you advice me something better in design terms / point out my errors.
Thank you
This might be a situation where the template pattern (not to be confused with C++ templates) comes in handy. The public Render in the abstract class should be non-virtual, but have it call a private virtual function (e.g. DoRender). Then in the derived classes, you override DoRender instead.
Here's an article that goes into great depth describing the use of template pattern with private virtual functions.
Edit:
I started to put together an example of what I meant, and it seems like there's actually a broader flaw in the architecture. Your use of AbstractRenderer is somewhat frivolous since you're forcing each geometricalobject to be intimately aware of a particular renderer type.
Either the renderer should be able to work off the public methods of Renderables, or Renderables should be able to work off the public methods of the Renderer. Or perhaps you can give the concrete renderers a Renderable factory if there really needs to be such an intimate connection. I'm sure there are some other patterns that would fit well, too.
I don't see what your code wants to achieve. You derive Renderable objects to DirectXRenderables and OpenGLRenderables and then provide OpenGL or DirectX functionality in something derived from Renderer. A specific thing uses another specific thing so to speak.
It would seem much more reasonable to identify general rendering functions, make them pure virtual members of your abstract renderer and implement them in DirectXRenderer and OpenGLRenderer. Then a IRenderable would have a member function draw roughly like this:
void draw(const AbstractRenderer& r) {
//general stuff
r.drawLine(...);
//only possible on directX
if(DirectxRenderer rx = dynamic_cast<DirectxRenderer*>(r)) {
//...
} else {
//throw exception or do fallback rendering in case we use something else
}
}
Using templates, you could split the IRendable into two classes, one for each of the two renderer types. This is probably not the best answer, but it does avoid the need for the dynamic cast:
template <typename RendererType>
struct IRenderable {
virtual void Render(RendererType* renderer) const = 0;
}
template <typename RendererType>
class AbstractGeometricalObject : public IRenderable<RendererType> {
virtual void Render(RendererType* renderer) const { ... }
};
class DirectxGeometricalObject : public AbstractGeometricalObject<DirectxRenderer> {
// this class will now require a void Render(DirectxRenderer* renderer)
}
Use a setter to set the renderer var and cast it to the proper type in that one place.
See if the Bridge design pattern helps you: "Decouple an abstraction from its implementation so that the two can vary independently." In your example, AbstractGeometricalObject would point to an implementation, a pure virtual interface with platform-specific subclasses. The tricky part is taking the time to discover that interface.
Let's distance from compilers and consider theory. If DirectxGeometricalObject::Render expects DirectxRenderer as parameter and not any AbstractRenderer, then some other OtherGeometricalObject::Render will probably expect OtherRenderer object as parameter.
So, different implementations of AbstractGeometricalObject have different signatures of their Render methods. If they are different, then there is no purpose in defining the virtual AbstractGeometricalObject::Render.
If you declare AbstractGeometricalObject::Render(AbstractRenderer*), then you should be able to pass any renderer to any geometrical object. In your case, you can't because dynamic_cast would fail.