【问题标题】:Reversal of Upcasting for Component system分量系统向上转换的反转
【发布时间】:2012-08-16 14:34:50
【问题描述】:

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

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

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

有没有可以借鉴的例子?

【问题讨论】:

  • 这对于组件向量是不可能的。使用 *Components 或 shared_ptr. 的向量
  • 抱歉忘了说它是一个指针向量

标签: c++ components polymorphism upcasting


【解决方案1】:

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

【讨论】:

    【解决方案2】:

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

    既然知道了,就可以这样做(假设component 的类型是Component*):

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

    不是说dynamic_cast会失败=>如果实际组件类型不适用,上面可以将specific设置为nullptr。这一点,以及它比其他类型转换慢的事实使它成为 C++ 类型转换中最不受欢迎的。

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-10-06
        • 2016-12-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多