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.
Polymorphism in Function Overloading In computing, polymorphism is a property of object oriented programming in which a function can take different forms based on the number of arguments and their data types. All the functions will have the same name, but they will differ in their arguments.
Function overloading means one function can perform many tasks. In C++, a single function is used to perform many tasks with the same name and different types of arguments. In the function overloading function will call at the time of program compilation. It is an example of compile-time polymorphism.
The compiler selects which overloaded function to invoke based on the best match among the function declarations in the current scope to the arguments supplied in the function call. If a suitable function is found, that function is called. "Suitable" in this context means either: An exact match was found.
Function overloading is a feature that allows us to have same function more than once in a program. Overloaded functions have same name but their signature must be different.
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:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With