【问题标题】:How do I get the derived class from a interface?如何从接口获取派生类?
【发布时间】:2019-11-05 19:47:06
【问题描述】:

在尝试在 C++ 中创建实体-组件-系统时,由于缺乏对语言的了解,我遇到了一些问题。

有了一个类 Entity,它持有接口 IComponent(它的作用更像是一个标有“我持有数据”的标志),我有一个方法 添加,如果其中没有另一个相同类的 IComponent,则将组件添加到实体中。

这是一个过于简化的示例代码:

struct IComponent{};

struct Foo : IComponent{ int x;};
struct Bar : IComponent{ int y; };

class Entity{
    vector<IComponent*> entityComponents;

    void Add(IComponent* componentToAdd){
        if("entityComponents" does not contain the class of "componentToAdd")
            entityComponents.add (componentToAdd)

    }
}

我的预期结果是

Entity e;
Foo f;
Bar b;
Foo anotherF;

e.Add(f); // Works
e.Add(b); // Works
e.Add(anotherF); // Does not work because another 
                 //item in the array already inherits Foo

但我不知道如何从 IComponents 列表中获取 Foo 和 Bar 的基类并检查它们是否重复。

我怎样才能得到它们?如果 Foo 在 IComponent 列表中,我如何将 IComponent 转换为 Foo?

【问题讨论】:

  • vector&lt;IComponent&gt; 你可能不希望这样,但vector&lt;IComponent*&gt;。另见:Object slicing
  • 您打算如何处理所有这些 IComponent 实例?除了Add,你打算怎么用?
  • @IgorTandetnik 我的错,修复了它们。我计划获取它们并修改其中的数据。使用 GetComponent()、HasComponent()、RemoveComponent()...
  • 那么,您打算如何实施,例如,HasComponent&lt;Bar&gt;?一旦你知道了,你也会知道如何防止Add中的重复。
  • 通过检查类 Bar 是否在 IComponent* 列表中并且它们返回 true,但我不知道该怎么做。恐怕我的问题可能重复。

标签: c++ reflection interface entity-component-system


【解决方案1】:

正如Bar Stool 所说,我的解决方案是

template<typename T>
bool HasComponent(){
  for(Component* component: this->components)
        if(T* casted = dynamic_cast<T*>(component))
                return true;           
  return false;

}

稍后只需检查“HasComponent()”是否为假,然后添加它

【讨论】:

  • if 有点混乱。 :S 你不需要保存结果 :) 试试:if (dynamic_cast&lt;T*&gt;(component)) return true;
【解决方案2】:

结帐dynamic_cast。您可以尝试将指向基类的指针转换为指向派生类的指针。如果实例化的对象不是派生类型并且在这种情况下返回 null,则它会失败。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-12-19
    • 1970-01-01
    • 2012-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-14
    相关资源
    最近更新 更多