【问题标题】:"Implementation" of the object hierarchy - "the easiest way" or how to avoiding virtual inheritance?对象层次结构的“实现”——“最简单的方法”或如何避免虚拟继承?
【发布时间】:2014-06-29 05:02:45
【问题描述】:

我有一些非常复杂的虚拟对象层次结构,将 3D 引擎中的所有元素表示为抽象类(接口)。

例如,我有Renderable 哪个父级是Sizeable(使用getSize() 方法)。 Sizeable 继承自 Positionable(与 getPosition())等。

该结构很好且符合逻辑(例如,3D 模型为Renderable,用于蒙皮的骨骼骨骼为Sizeable,而相机仅为Positionable)。

还有一个“超级班”,Engine3D。

我的目标是:

我必须为那个“图形事物”(模块)编写“实现”。这将是 DirectX 的“实现”。 目标:使用我的“实现”的程序员可以快速简单地切换到其他的(他使用的实现对他来说几乎是透明的)。

我想保持这种状态:

//choosing module "implementation" ("implementation" mentioned here only)
Engine3D * engine = new MyEngine3D();

Renderable * model = engine->createModel(...);
//line above will return MyRenderable class in fact,
//but user (programmer) will treat it as Renderable

为什么我要创建“自己的”版本的Renderable 和所有其他版本?因为它们将共享一些“实现”特定的数据(DirectX 结构的指针等)。

我的问题是:

但是那样,我会创建一个“镜像”——原始模块对象层次结构的副本,每个类名前面都有My。此外,MyRenderable 必须同时继承自 Renderable(以覆盖render())和MySizeable(以获取 DirectX 矩阵等)。

这涉及到虚拟继承,确实使结构复杂化。

有没有更简单的方法?

我主要是在谈论避免虚拟多继承(我猜只是多继承就可以了)。

【问题讨论】:

    标签: c++ inheritance virtual multiple-inheritance virtual-inheritance


    【解决方案1】:

    您绝对应该避免对象层次结构和渲染实现的强耦合。我的建议是将所有 DirectX 特定代码移动到对象层次结构之外的类中,例如 IRenderer 接口和 DirectXRenderer 实现。将指向IRenderer 的引用或指针添加到所有必须绘制东西的类(Renderable 等)。所有对象类都必须使用您自己的矩阵等实现,以使它们独立于实际渲染后端的数据结构。

    【讨论】:

    • 我(部分)按照我描述的方式来做。我将 DirectX 特定代码移动到与我的抽象数据树相对应的对象层次结构中。但是你知道,Renderable 有通用的 render() 方法,Materialable 有通用的着色器方法等 - 它不仅仅是一个可以处理所有类型(线条、骨骼、网格......)的统一 IRenderer - 我使用 DirectX 不仅使用 render() 但也用于皮肤计算、着色器设置、纹理指针等 - 该层次结构中的一些对象具有它们,而其中一些没有。但是,我仍然认为将 IS-A 更改为 HAS-A 有一些意义。
    • 您不必使用单个 IRenderer 实现。如果您需要,渲染器下方也可以有另一个 - 不太复杂的 - 层次结构,尽管您不应该在渲染层次结构中复制对象层次结构。关键是,如果您曾经打算使用像 OpenGL 之类的另一个渲染器或其他东西(关注点分离),那么您需要在渲染器和抽象依赖关系的对象之间建立一个(薄)接口。
    • 好的,但是你知道 - “渲染器和游戏对象之间的接口”(玩家、NPC 等)将它们与 OGL/DirectX 分开,应该是我的层次结构的对象(即是创建它们的目的)。该层次结构的复杂性在于处理 DirectX/OGL 操作(着色器、纹理、光线计算、矩阵......)。所以它是:Player(使用他的组件)->Renderable(我的层次结构)->RenerableDX(我的实现)或Player->Renderable->RenderableOGL
    • 也许我理解错了。我认为创建此对象层次结构的目的也是为了使用户能够通过将类实例添加到树中来构建场景。
    • 好的,我理解正确。我写了“将类 instances 添加到树”以形成一个场景。当然,用户不需要创建新的类。看看一些已经存在的 3D 引擎实现。他们中的大多数使用我提到的方法。一个例子是 OGRE 引擎,它使用单独的类 RenderSystem 和实现 GLRenderSystem 等。场景构建类都没有使用任何特定于 OpenGL 或 DirectX 的代码。
    猜你喜欢
    • 2010-10-16
    • 1970-01-01
    • 2012-08-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-22
    • 1970-01-01
    • 2012-03-17
    相关资源
    最近更新 更多