我在应用程序架构方面有以下问题,我愿意解决它(抱歉,文字太多)。
我正在构建一个游戏引擎原型(prototype)并且我有基础抽象类 AbstractRenderer
(我将使用 C++ 语法,但问题仍然是一般性的)。
假设这个渲染器有一些派生的实现,比如说 DirectxRenderer
和 OpenglRenderer
。
现在,假设这些渲染器中只有一个(让我们坚持基于 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/