How to cast a unique_ptr of base class to template derived class?

22 views Asked by At

I have a base class for components and a derived class for my ECS arch. I need to store different types of values so my derived class is a template class.

Base class & template derived class :

class Component
{
public:
    enum Type
    {
        POSITION,
        VELOCITY,
    };
    Component() {};
    virtual ~Component() {};
};

template <class T>
class ComponentLeaf : public Component
{
public:
    ComponentLeaf(T value): value(value) {};
    ComponentLeaf(const ComponentLeaf<T>& other): value(other.value) {};
    T value;
};

Entity .h :

class Entity
{
public:
    Entity();
    Entity(const Entity& other);
    Entity(Entity&& other);
    Entity& addComponent(Component::Type type, std::unique_ptr<Component> component);
    std::unique_ptr<Component>& getComponent(Component::Type type);
    std::map<Component::Type, std::unique_ptr<Component>> _components;
};

Entity .cpp :

Entity::Entity()
{

}

Entity::Entity(const Entity& other)
{

}

Entity::Entity(Entity&& other)
{
    for (auto it = other._components.begin(); it != other._components.end(); it++)
    {
        this->_components[it->first] = std::move(it->second);
    }
}

Entity& Entity::addComponent(Component::Type type, std::unique_ptr<Component> component)
{
    this->_components[type] = std::move(component);
    return *this;
}

std::unique_ptr<Component>& Entity::getComponent(Component::Type type)
{
    return this->_components[type];
}

When I try do run the following code, the pos returned is NULL. I don't really know if my initialization and downcasting are wrong. I spend a lot of time debugging but I don't find my mistake.

main.cpp :

Entity e = Entity()
    .addComponent(Component::POSITION, std::make_unique<ComponentLeaf<float>>(2.0f))
    .addComponent(Component::VELOCITY, std::make_unique<ComponentLeaf<float>>(1.0f));
ComponentLeaf<float>* pos = static_cast<ComponentLeaf<float>*>(e.getComponent(Component::POSITION).get());
std::cout << pos->value << std::endl; // pos is NULL (error in access reading)
0

There are 0 answers