我正在制作一个基于文本的冒险游戏(我知道是原始的),但是遇到了问题。我想让玩家拿起一个物品,然后根据它所属的Item
的子类将它自动放置在它所属的位置。我进行了设置,以便当播放器键入“ get”后跟当前房间中对象的名称时,将调用以下功能:
void Game::PickUp(Item * item)
{
m_map.at(m_player.GetLoc())->RemoveItem(item); //Remove item from the room
m_player.AddItem(item); //Add item to the player
}
在Player
类中,我按如下方式重载了AddItem(…)
:
void AddItem(Armor* armor)
{
delete m_armor;
m_armor = armor;
}
void AddItem(Weapon* weapon)
{
delete m_weapon;
m_weapon = weapon;
}
void AddItem(Shield* shield)
{
delete m_shield;
m_shield = shield;
}
void AddItem(Item* item)
{
m_pack.push_back(item);
}
运行代码时,它仅调用void AddItem(Item* item)
,这很有意义,因为这就是传递给上一个函数的内容,但是由于传递的对象保存在vector<Item*>
中,因此我无法传递和其他一样。有没有办法检测要传递的对象的子类并调用正确的重载?
答案 0 :(得分:0)
您要寻找的被称为multiple dispatch。由于确定哪个覆盖被调用是在编译时根据参数的静态类型确定的,因此您需要调用一个可以利用对象的运行时类型的函数,然后再调用原始的{ {1}}个对象。
在您的Player
基类中,您将为此函数声明基数:
Item
它定义为
virtual void AddToPlayer(Player &player);
这与您已经做的没什么不同。但是,您可以为每个类添加void Item::AddToPlayer(Player &player) {
player.AddItem(*this);
}
的替代,其定义与上面给出的基类相同。由于每个定义中AddToPlayer
的类型将不同,因此将调用*this
的不同重载。