来自Derived类的调用函数存储在具有基类类型的Map中

时间:2016-12-03 21:49:28

标签: c++ inheritance derived-class

我尝试使用Gameobject和Components制作游戏引擎,类似于Unity。我有一个组件类:

class Component
{
public:
    virtual void DoTheThing(){//Doing the thing};
}

从Component派生的Texture Class,具有重写函数:

class Texture : public Component
{
public:
    void DoTheThing(){//Doing a different thing};
}

带有组件映射的GameObject类,用于存储派生组件:

class GameObject
{
private:
    map<string, Component> components;
    Texture texture;
    components["id"] = texture;

public:    
    Component getComponent(string id){ return components[id];}
}

最后:

int main(int argc, char* args[])
{
    GameObject gameObject;
    gameObject.getComponent("id").DoTheThing();
}

我想要的是能够调用派生类中存在的DoTheThing(),但它只调用基类中的DoTheThing()。

2 个答案:

答案 0 :(得分:0)

问题出在您的GameObject课程中 让我把它减少到相关部分:

class GameObject {
private:
    map<string, Component> components;

    // ...

public:
    Component getComponent(string id){ /* do something and return a component */ }
};

这里你实际上正在切割你的对象 这就是调用基类方法的原因。

如果您不知道切片是什么以及如何避免切片,我建议您不要写一些类似于Unity 的内容。
我建议您阅读this Q/A了解更多详情。

答案 1 :(得分:0)

您的容器被指定为包含Component个对象,所以当您这样做时         components["id"] = texture;  实际上,您在地图中放置了一个Component对象,并在对象texture上调用了复制构造函数。

为了确保多态性,容器必须包含指针,而不是预定义的类。

class Component
{  public:  virtual void DoTheThing() {cout << "Component\n";} };
class Texture : public Component
{  public:  void DoTheThing() override { cout << "Texture\n"; } };

class GameObject
{   map<string, Component*> components; Texture texture;
    public:
        GameObject() { components["id"] = &texture; }
        Component& getComponent(string id) { return *components[id]; }
        // Remember to return a Component& (or Component*) here, not a
        // Component (by value) because otherwise you would end up with a 
        // base-class Component object copied from the initial Texture
        // object saved in the map.
};

int main(void)
{   GameObject gameObject;
    gameObject.getComponent("id").DoTheThing();
    return 0;
}

<强>输出: 质地