For example, I have a game, which has some tools to increase the ability of the Player:Tool.hclass Tool{public:    std::string name;};And some tools:Sword.hclass Sword : public Tool{public:    Sword(){        this->name=Sword;    }    int attack;};Shield.hclass Shield : public Tool{public:    Shield(){        this->name=Shield;    }    int defense;};MagicCloth.hclass MagicCloth : public Tool{public:    MagicCloth(){        this->name=MagicCloth;    }    int attack;    int defense;};And then a player may hold some tools for attack:class Player{public:    int attack;    int defense;    vector<Tool*> tools;    void attack(){        //original attack and defense        int currentAttack=this->attack;        int currentDefense=this->defense;        //calculate attack and defense affected by tools        for(Tool* tool : tools){            if(tool->name==Sword){                Sword* sword=(Sword*)tool;                currentAttack+=sword->attack;            }else if(tool->name==Shield){                Shield* shield=(Shield*)tool;                currentDefense+=shield->defense;            }else if(tool->name==MagicCloth){                MagicCloth* magicCloth=(MagicCloth*)tool;                currentAttack+=magicCloth->attack;                currentDefense+=magicCloth->shield;            }        }        //some other functions to start attack    }};I think it is difficult to replace if-else with virtual methods in the tools, because each tool has different properties, and each tool affects the player's attack and defense, for which the update of player attack and defense needs to be done inside the Player object.But I was not satisfied with this design, since it contains downcasting, with a long if-else statement. Does this design need to be corrected? If so, what can I do to correct it?
Is it a code smell to store generic objects in a container and then get object and downcast the objects from container?
design patterns;c++;generics