逆转组件系统的向上转换

时间:2012-08-21 09:09:25

标签: c++ components polymorphism upcasting

我目前正在研究用C ++编写的基于Component的游戏引擎。所有组件都继承自组件基类。场景中的所有组件都被上传到组件的向量中,如果它们可以迭代并Update(),则可以调用它们。

我正在尝试为组件提供通信系统。如果我有一个名为GetComponent<Type>()的函数,就像Unity一样,我可以在它被提升之前返回一个组件。

所以基本上我有一个upcasted组件,我想要反转它,所以它是它的原始类,然后通过函数返回它(就像以前的类)。这可能吗?如果有可能该组件如何知道它曾经是什么类?

有没有这样做我可以借鉴的例子?

3 个答案:

答案 0 :(得分:2)

我假设通过向上转换组件,意味着将指针(或引用)转换为指向基类的指针。在这种情况下,请使用dynamic_cast<Derived *>(pointer)(或dynamic_cast<Derived &>(reference)在运行时进行安全的转发。

答案 1 :(得分:1)

要使其正常工作,您必须先了解组件的原始类型,然后再将其添加到集合中(向上播放)。

知道这一点,可以这样做(假设component的类型为Component*):

SpecificComponent* specific = dynamic_cast<SpecificComponent*>(component);

不是dynamic_cast可以失败=&gt;如果实际组件类型不适用,则上述内容可以将specific设置为nullptr。那个,以及它比其他演员阵容慢的事实使它成为最不喜欢的C ++演员阵容。

您还可以查看boost :: polymorphic_downcast,它的功能类似。如果它在DEBUG模式下失败,则生成dynamic_cast并断言,但在RELEASE模式下执行速度更快static_cast

答案 2 :(得分:0)

如果你有RTTI,可以很容易地进行映射。我建议有2个函数GetComponentExact&amp; GetComponentDerived

template< typename Type >
Type* GameObject::FindComponentExact( size_t a_Index )
{
    size_t found = 0;
    for( ComponentVector::iterator itrCur = m_Components.begin(), itrEnd = m_Components.end(); itrCur != itrEnd; ++itrCur )
        if( typeid( Type ) == typeid( *(*itrCur) ) && found++ == a_Index )
            return static_cast< Type* >( *itrCur );
    return NULL;
}

template< typename Type >
Type* GameObject::FindComponentDerived( size_t a_Index )
{
    size_t found = 0;
    for( ComponentVector::iterator itrCur = m_Components.begin(), itrEnd = m_Components.end(); itrCur != itrEnd; ++itrCur )
        if( dynamic_cast< Type* >( *itrCur ) && found++ == a_Index )
            return static_cast< Type* >( *itrCur );
    return NULL;
}

这就是它在我的引擎中的样子,我有一个索引,默认为0,让我遍历所有实例,因为我可以拥有一个特定组件的多个实例。