好吧,这个标题有点拗口,我想这可能就是为什么很难通过谷歌或这个网站找到答案的原因。可能只是我不知道如何正确表达问题,但这里是:
我在 SimpleOpenGLRenderer
类中有一系列方法,它们都采用扩展 Model
类的单个参数。所以想法是,根据模型的类型,渲染器将调用知道如何渲染它的正确方法。这是一个基于问题的简化可执行示例:
#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);
}
示例的输出是:
Render the cube.
Throw an exception, my renderer does not support the model type you have provided.
对于经验丰富的 C++ 开发人员来说,这似乎很明显,这并没有按计划工作,但对我来说却没有意义。在运行时,我不知道传递给渲染器的 Model
的确切类型(因此尝试重载来解决它)。来自 Java 背景,我之前使用过这种技术,在 Java 中,调用的方法将是与参数的 runtime 类型最匹配的方法。在 C++ 中,它似乎与引用的编译时类型相匹配,即使该引用最终可能是一个子类——在我看来——它更好地匹配另一个函数。
到目前为止,我一直认为这种运行时类型匹配是理所当然的。它在 C++ 中根本不存在,还是我走错了路?我应该在 C++ 中做一些不同的事情来实现它吗?
谢谢,
加里。
最佳答案
C++ 中的重载在编译时根据参数的静态类型解决。
有一种称为“双重调度”的技术可能有用:
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);
}
请注意,Renderer
基类需要包含 SimpleOpenGLRenderer
当前所做的所有重载。如果您希望它特定于 SimpleOpenGLRenderer
存在哪些重载,那么您可以在 Model
中放置一个特定于 Simple 的调度函数,或者您可以忽略此技术而使用 dynamic_cast
在 SimpleOpenGLRenderer::renderModel
中反复测试类型。
关于c++ - 将重载函数与其多态参数匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6897662/