C++继承问题

标签 c++ abstract downcast

我在应用程序架构方面有以下问题,我愿意解决它(抱歉,文字太多)。

我正在构建一个游戏引擎原型(prototype)并且我有基础抽象类 AbstractRenderer (我将使用 C++ 语法,但问题仍然是一般性的)。

假设这个渲染器有一些派生的实现,比如说 DirectxRendererOpenglRenderer

现在,假设这些渲染器中只有一个(让我们坚持基于 DirectX)有一个名为 IDirect3D9Device* m_device; 的成员显然此时一切正常 - m_device code> 在 DirectxRenderer 内部使用,不应在抽象 AbstractRenderer 父类(super class)中公开。

我还添加了一些抽象的渲染接口(interface),例如IRenderable。这意味着一个简单的纯虚方法 virtual void Render(AbstractRenderer* renderer) const = 0;


这就是一些问题开始的地方。假设我正在对某个场景进行建模,那么,这个场景中可能会有一些几何对象。

我创建了抽象父类(super class) AbstractGeometricalObject 和派生的基于 DirectX 的实现 DirectxGeometricalObject。第二个负责存储指向 DirectX 特定顶点和索引缓冲区的指针。

现在 - 问题。

AbstractGeometricalObject 显然应该派生 IRenderable 接口(interface),因为它在逻辑上是可渲染的

如果我从 AbstractGeometricalObject 派生我的 DirectxGeometricalObject,第一个应该有 virtual void Render(AbstractRenderer* renderer) const { ... } 方法,而 Abstract... 东西带来了一些麻烦。

查看代码以获得更好的解释:

现在我的类(class)如下所示:

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(...);
}

我知道我可能担心得太多了,但在如此简单的情况下,这种沮丧意味着如果我的应用程序增长,我可能被迫进行大量沮丧。

当然,我想避免这种情况,所以请您在设计方面给我一些更好的建议/指出我的错误。

谢谢

最佳答案

这可能是模板模式(不要与 C++ 模板混淆)派上用场的情况。抽象类中的public Render 应该是非虚的,但是让它调用一个私有(private)的虚函数(例如DoRender)。然后在派生类中,您改写 DoRender。

这是一篇深入描述 template pattern with private virtual functions 用法的文章.

编辑:

我开始整理一个例子来说明我的意思,但似乎架构中实际上存在更广泛的缺陷。您对 AbstractRenderer 的使用有些轻率,因为您强制每个几何对象密切注意特定的渲染器类型。

渲染器应该能够使用 Renderables 的公共(public)方法,或者 Renderables 应该能够使用 Renderer 的公共(public)方法。或者,如果确实需要这种紧密联系,您可以为具体渲染器提供一个可渲染工厂。我敢肯定还有其他一些模式也很适合。

关于C++继承问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3250217/

相关文章:

c++ - 在 QTextEdit 中启用/禁用语法突出显示

c++ - 这个指针到底发生了什么

c++ - 防止在头文件之外创建子类

java - jvm如何处理java中的抽象类

java - 存储和打印存储在抽象类的子类的对象数组中的值

Java - 无法从子类对象访问抽象方法

c# - 将基类转换为派生类

c++ - 外部while循环有什么问题?

c++ - 从(基对象的基引用)到(派生类引用)的静态转换

c++ - 基于类实例的自动方法选择