将重载函数与其多态参数匹配

Gya*_*uyn 18 c++ polymorphism overloading function

好吧,标题是满口的,我认为这可能是为什么很难通过谷歌或这个网站找到答案.可能只是因为我不知道如何正确表达问题,但这里有:

我在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);
}
Run Code Online (Sandbox Code Playgroud)

该示例的输出是:

Render the cube.
Throw an exception, my renderer does not support the model type you have provided.
Run Code Online (Sandbox Code Playgroud)

对于一个经验丰富的C++开发人员来说,这似乎是显而易见的,但这并不是按计划运行的,但这对我来说没有意义.在运行时,我不知道Model传递给渲染器的确切类型(因此尝试重载以解决它).来自Java背景,我在Java之前和之前使用过这种技术,调用的方法最适合参数的运行时类型.在C++中,它似乎与引用的编译时类型匹配,即使该引用最终可能是一个子类 - 在我看来 - 更好地匹配另一个函数.

到目前为止,我已将此运行时类型匹配视为理所当然.它是否根本不存在于C++中,还是我以错误的方式解决这个问题?我应该在C++中做些不同的事情来实现它吗?

谢谢,

加里.

Ste*_*sop 17

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);
}
Run Code Online (Sandbox Code Playgroud)

请注意,Renderer基类需要包含SimpleOpenGLRenderer当前执行的所有重载.如果你希望它特定于SimpleOpenGLRenderer存在什么重载,那么你可以放入一个特定于Simple的调度函数Model,或者你可以忽略这种技术,而是dynamic_cast反复使用SimpleOpenGLRenderer::renderModel来测试类型.

  • 谢谢.我之前没有使用过这种模式.我想在Java中可能不常见.我做了一些测试,我想我可能会回到`dynamic_cast`解决方案.我希望有更优雅的东西,但双调度/访问者模式似乎引入了各种各样的依赖关系和紧密耦合,我不太热衷于此. (2认同)