The actual reason you get that error is that the way you have defined the range-based for, you are retrieving objects by copy rather than reference:
for (EngineComponent component: this->engineComponents)
{
// component is a copy of the object in the list
}
EngineComponent
is a super-class and so there's no implicit cast to a derived class. If you try to copy a DrawableEngineComponent
out of a list of EngineComponent
the compiler has no way of knowing if the source object is really a derived class.
Standard containers don't really handle polymorphic objects very well. A much better solution is to use std::shared_ptr
to store pointers to the objects.
std::list<std::shared_ptr<EngineComponent>> myList;
myList.push_back(std::make_shared<DrawableEngineComponent>());
This will wrap a DrawableEngineComponent
in a shared pointer and store it in the list. It can be accessed in a similar way to your original method:
for (auto& component: engineComponents)
{
component->Update();
}
But this time you have a fully polymorphic object you can call. If the object overloads the Update()
method in a sub-class then it's this that will be called. You can also use casting to get a pointer to the sub-class if that's what you need:
for (auto& component: engineComponents)
{
auto pDrawComponent = dynamic_cast<DrawableEngineComponent*>(component.get());
if (pDrawComponent)
{
// it's drawable
}
}