【问题标题】:C++: Overloads for multiple derived classes within another classC ++:另一个类中的多个派生类的重载
【发布时间】:2018-06-20 01:55:54
【问题描述】:

我正在制作一个基于文本的冒险游戏(我知道是原创的。)但我遇到了一个问题。我想让玩家拿起一个物品,然后根据它所属的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*> 中,我不能将它作为其他任何东西传递.有没有办法检测被传递对象的子类并调用正确的重载?

【问题讨论】:

    标签: c++ polymorphism


    【解决方案1】:

    您要查找的内容称为multiple dispatch。由于在编译时根据参数的静态类型确定调用哪个覆盖,因此您需要调用一个可以利用对象的运行时类型的函数,然后回调到原始 @ 987654322@对象。

    在您的 Item 基类中,您将声明此函数的基本情况:

    virtual void AddToPlayer(Player &player);
    

    定义为

    void Item::AddToPlayer(Player &player) {
        player.AddItem(*this);
    }
    

    这与您已经拥有的没有什么不同。但是,您可以将AddToPlayer 的覆盖添加到每个类,其定义与上面给出的基类相同。由于*this 的类型在每个定义中都会不同,因此将调用不同的Player::AddItem 重载。

    【讨论】:

    • 我正在尝试实现这一点,但由于我的 Unit.h 标头中有 #include "Item.h",我的编译器不会让我在 Item.h 中使用 #include "Unit.h"PlayerUnit 的子类)。有解决办法吗?
    • @JasonNickPorter 您可以通过简单地说class Player;class Unit; 转发声明一个类,而不包括定义该类的标头。然后在需要类的详细信息时在 .cpp 文件中包含头文件。
    猜你喜欢
    • 2016-12-12
    • 1970-01-01
    • 2013-05-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-01
    相关资源
    最近更新 更多