0

我目前正在开发一个用 c++ 编写的基于组件的游戏引擎。所有组件都继承自组件基类。场景中的所有组件都被向上转换为组件的向量,它们可以被迭代并且Update()可以被调用。

我正在尝试为组件设计一个通信系统。如果我有一个名为GetComponent<Type>()Like Unity 的函数,我将能够从它被向上转换之前的状态返回一个组件。

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

有没有我可以学习的例子?

4

3 回答 3

2

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

于 2012-08-21T09:16:48.277 回答
1

为此,您必须在将组件添加到集合(向上转换)之前知道组件的原始类型。

所以知道这一点,它可以这样做(假设component是 type Component*):

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

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

也可以看一下 boost::polymorphic_downcast,功能类似。如果在 DEBUG 模式下失败,它会生成dynamic_cast并断言,但static_cast在 RELEASE 模式下会更快。

于 2012-08-21T09:45:09.320 回答
0

如果您有 RTTI,则可以很容易地进行映射。我建议有 2 个函数GetComponentExact& 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 的索引,让我可以遍历所有实例,因为我可以拥有多个特定组件的单个实例。

于 2012-08-21T09:57:18.133 回答