1

I'm implementing a game engine in C++ which uses an ECS (Entity-Component-System).

Each GameObject can have multiple Components (stored in GameObject's std::vector<Component*> _components).

I have a method that allows me to get a Component of a GameObject by specifying the type of Component I want:

// In GameObject.h
template <typename T> T* GetComponent() {
    for (Component* c : _components) {
        if (typeid(*c) == typeid(T)) return (T*)c;
    }
    return nullptr;
}
// In main.cpp
RandomComponent* RC = gameObject.GetComponent<RandomComponent>();

Now let's say I have those Components defined:

class TerrainComponent { /* ... */ }
class PerlinTerrainComponent : public TerrainComponent { /* ... */ }
class FlatTerrainComponent : public TerrainComponent { /* ... */ }
// And possibly many more

And have world GameObjects, which all have a TerrainComponent's derived class attached to it.

My problem is that I would need a way to get the TerrainComponent of a world, like so:

TerrainComponent* TC = world.GetComponent<TerrainComponent>();

And get any type of TerrainComponent attached to the world (which, in reality, will be a TerrainComponent derived class).

Is it possible, in C++, to implement a method that would allow me to do that (get all derived classes of a class), without having to manually update a list of TerrainComponent derived classes?

1
  • 2
    Not sure to understand your question but maybe if you replace if (typeid(*c) == typeid(T)) by if(dynamic_cast<T*>(c) != nullptr ) it will do what you want.
    – user6547518
    Commented Jan 6, 2022 at 21:31

1 Answer 1

1

Assuming these classes are all polymorphic/dynamic (which they need to be to use typeid like this), you can just use dynamic_cast instead:

template <typename T> T* GetComponent() {
    for (Component* c : _components) {
        if (T *tc = dynamic_cast<T *>(c)) return tc;
    }
    return nullptr;
}
3
  • Notice this only works if the objects are polymorphic, ie with at least one virtual method.
    – user8143588
    Commented Jan 6, 2022 at 21:41
  • @Jellyboy: as does the typeid method.
    – Chris Dodd
    Commented Jan 6, 2022 at 23:00
  • Had not thought about a dynamic_cast. It did what I was looking for! Thanks
    – FeuFeve
    Commented Jan 7, 2022 at 0:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.