I'm trying to make a game engine using Gameobject and Components, similar to Unity. I have a Component Class:
class Component
{
public:
virtual void DoTheThing(){//Doing the thing};
}
A Texture Class derived from Component, with an overridden function:
class Texture : public Component
{
public:
void DoTheThing(){//Doing a different thing};
}
A GameObject Class with a Component Map which stores derived components:
class GameObject
{
private:
map<string, Component> components;
Texture texture;
components["id"] = texture;
public:
Component getComponent(string id){ return components[id];}
}
And finally:
int main(int argc, char* args[])
{
GameObject gameObject;
gameObject.getComponent("id").DoTheThing();
}
What I want is to be able to call the DoTheThing() that exists in the derived class, but it only calls the DoTheThing() in the base class.
Your container is specified to contain Component
objects, so when you do
components["id"] = texture;
you are actually putting a Component
object in the map, with the copy constructor invoked on the object texture
.
To ensure polymorphism your container must hold pointers, not a predefined class.
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;
}
OUTPUT: Texture