我目前正在研究用C ++编写的基于Component的游戏引擎。所有组件都继承自组件基类。场景中的所有组件都被上传到组件的向量中,如果它们可以迭代并Update()
,则可以调用它们。
我正在尝试为组件提供通信系统。如果我有一个名为GetComponent<Type>()
的函数,就像Unity一样,我可以在它被提升之前返回一个组件。
所以基本上我有一个upcasted组件,我想要反转它,所以它是它的原始类,然后通过函数返回它(就像以前的类)。这可能吗?如果有可能该组件如何知道它曾经是什么类?
有没有这样做我可以借鉴的例子?
答案 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,让我遍历所有实例,因为我可以拥有一个特定组件的多个实例。