【问题标题】:Proxy class for polymorphic type, using templates多态类型的代理类,使用模板
【发布时间】:2014-09-03 03:50:33
【问题描述】:

这是针对“游戏引擎”的一些编程练习。我所有的游戏对象都是基于组件的,其中每个组件都向其父游戏对象添加一个功能,所有这些组件都来自一个基 Component 类,该基类具有使其具有多态性的虚拟方法。

当我从 XML 文件中读取这些游戏对象定义时,一些组件需要了解其他组件,例如物理组件需要了解用于物理计算的变换组件。但是,如果 XML 文件中不存在这些组件,那么它偶尔会抛出令人讨厌的空指针和无休止的兔子洞调用堆栈,以寻找我在半睡半醒时捏造的 XML 错字。

我的解决方案是在 XML 文件中设置一个节点,作为这种类型的组件应该存在的断言,如果不存在则可能抛出异常或其他适当的操作。 例如。

<ComponentRequirement type="ComponentTransform">myTransformComponent</ComponentRequirement>

所以我需要一种在 C++ 中表示它的方法。第一个想法,模板类根据它所代理的组件类型进行更改,因为此类需要像它们的未代理组件一样工作。只要类是模板类,我已经通过一些运算符重载解决了这个问题。

template <class T>
class ComponentRequirement {
public:

    T* operator->() { (I chose the arrow operator because the CompReq class will never be referenced as a pointer)
        return this->component;
    }

//Other unrelated functions . . . 

private:
    T* component;
};

在编译时这一切都很好,因为我只能说

ComponentRequirement<ComponentTransform> req = ComponentRequirement("myComponentTransform");

但是当我读取 XML 时,我需要能够从字符串中指定模板类型来代替将是什么。我认为哈希图可以做到这一点,但我认为类型名称甚至“不是”任何东西除了人类可读的编译器提示之外,因此我不能将其用作哈希图值。

这可以做到吗?我该如何实施?将一些字符串文字插入“魔法黑盒”并获得可用作模板参数的内容。如果它有帮助,那么将成为“T”值的所有内容都是多态的。 或者我的问题有更好的解决方案。它需要能够充当我放入其中的任何组件,并且需要在运行时可识别。

编辑 1:

在我的组件中,我有一个读写功能。如果我阅读了那里的组件要求,我可以确保模板具有正确的值,因为每个组件都是独立的。 然后,我可以使用虚拟函数和 gameobject 类中的一些函数来评估需求,以检查它是否是有效的配置。这可以解决问题。

【问题讨论】:

  • 我知道这没什么用,但最好的答案是在一本名为 Game Coding Complete 的书中。他们详细介绍了如何在 C++ 中实现 Actor 系统。
  • 感谢 MorphingDragon 的建议。它是否进入演员的数据驱动样式加载?因为那是我的症结所在,也是我问这个问题的原因。不过,我几乎已经得到了它的工作代码。它只是我目前正在处理的文件加载故障保护:)
  • 他们在那本书中描述的游戏引擎完全是数据驱动的。

标签: c++ class templates polymorphism proxy-classes


【解决方案1】:

乍一看,我会使用工厂模式来解决您的问题。这样,您可以创建类以在给定不同字符串的情况下创建对象,而无需在编译时指定所需的确切类,这与普通类型的构造函数不同。我看到人们使用的类比是虚拟构造函数。

http://www.oodesign.com/factory-pattern.html

本质上,您将拥有一张工厂地图(创建者对象)。

  1. 为您的组件定义一些顶级接口,例如 IComponent。
  2. 为您要生成的具有 Create Instance 方法的每个组件定义一个工厂类。我建议 Create Instance 方法应该是 IFactory 等接口的一部分。
  3. 在您的程序设置过程中,创建您的地图并将工厂分配给特定的键。 ActorCreator["MyComponent"] = new MyComponentFactory();
  4. 当您想要创建从 XML 节点读取的对象时,您只需在返回的工厂上调用键的创建实例方法。 auto myComponent = ActorCreator[readXML]->CreateInstance();
  5. 您现在拥有一个actor/components,其具体类型已在运行时而不是编译时确定。

【讨论】:

  • 呵呵,我倒是真的想到了。我的组件的实际“构造”就是这样工作的。虽然,如果我要那样做需求,我怎么能专门化这个类,让它像组件本身一样工作呢? PS。所以 cmets 不喜欢段落 :(
  • 这是一种常见的模式。
  • 我试试看!如果可行,我将编辑我的帖子以添加任何改进:) 另请参阅我在先前评论中的编辑。编辑:我想创建功能可以自动专门化它。尽管我们可能会回到原点。因为它仍然需要一个类型。
  • 这取决于您和您的游戏架构。例如,在许多游戏中,组件至少需要响应 Update(dt) 和 Destroy(),以便将它们放入组件接口中。您需要好好思考并问自己游戏引擎中所有组件的基本行为是什么。当您确实需要知道具体类型时,这就是 dynamic_cast 的用途。您可能还会发现您的架构不适合数据驱动开发。
  • UnrealEngine 4 的 Actor/Component 层次结构非常简单(与 Unity 相比)。你可以考虑看看他们是如何做事的。 docs.unrealengine.com/latest/INT/Programming/UnrealArchitecture/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-09
  • 1970-01-01
  • 2010-12-05
  • 1970-01-01
  • 2012-12-26
  • 1970-01-01
相关资源
最近更新 更多