我正在用 C++ 创建一个小型模拟框架。我想将纯模拟相关的东西从显示中分离出来。所以我有这样的课程:
class Pointer : public SimulationObject {};
class Particle : public SimulationObject {};
class LearningObserver : public SimulationObject {};
它们都是从 SimulationObject 派生的,但只有一些(!)具有视觉表示:
class Renderable {
public:
virtual void render() const = 0;
//may also include reference to assosciated SimulationObject
}
class PointerRenderable : public Renderable {
void render() const { std::cout << "Render a pointer" << std::endl;
};
class ParticleRenderable : public Renderable {
void render() const { std::cout << "Render a particle" << std::endl;
};
现在,每当将新的 SimulationObject 添加到我的 Simulation(在运行时)中时,我都想检查是否有一个类可以渲染它。如果是这样,我想创建它的一个实例。我的第一个想法是使用多态性:
class AbstractRenderFactory {
virtual Renderable * provideRenderable(SimulationObject * so) const = 0;
};
class ConcreteRenderFactory {
void PointerRenderable * provideRenderable(Pointer * pointer) {
return new PointerRenderable();
}
// further provideRenderable's
};
但是,当覆盖方法显然不起作用时使用派生类型(基方法被调用)。这也是有问题的,因为该功能只会被部分定义。
另一个想法是提供类型的实际映射:
std::map<std::type_index, std::type_index> renderTable;
但我无法仅使用 type_info 获取实例。你有想法吗?
更新:我尝试使用访问者模式,但是我遇到了类似的问题。我的访问者类如下所示:
class RenderVisitor {
public:
virtual Renderable * visit(SimulationObject * so) {
// I would like to have this method abstract, but I could live with this
return 0;
}
};
class MyRenderVisitor : public RenderVisitor {
public:
Renderable * visit(Pointer * pointer) const {
return new PointerRenderable();
}
};
加上我的模拟部件的新基类。
class SimulationObject {
public:
Renderable * accept(RenderVisitor * renderer) {
return renderer->visit(this);
}
};
MyRenderVisitor 的访问方法显然不被识别为基类的覆盖,但我希望通过this指向实际(派生)类型,调用正确的方法(MyRenderVisitor 的方法)。
我的测试场景如下所示:
RenderVisitor * rv = new MyRenderVisitor();
SimulationObject * pointer = new Pointer();
Renderable * renderable = pointer->accept(rv);
renderable->render();
// renderable = 0 -> seg-fault
或者只是我的实施错误?