当我不知道 child 的类型时,C++ 从基类调用子类函数

标签 c++ polymorphism base-class

我有一个存储“InventoryItem”的库存。

struct InventoryItem{
Item* item;
unsigned int quantity;};

std::vector<InventoryItem> m_items;

我添加如下项目,m_inventory.addItem(bandage);

但是当我尝试调用从 Item 基类派生的 Bandages 的 use() 函数时,它调用了 Item 类的 use() 函数。

已经在Item类中这样声明了,

   // ....
public:
   // ....
    virtual void use(Player&){}
   // ....

它已经在 Bandage 类中这样声明了,

   // ....
class Bandage : public Item{
public:
   // ....
    virtual void use(Player&);
   // ....

在Bandage类中已经这样定义了,

void Bandage::use(Player& player)
{
    player.heal(35);
} 

当我尝试调用我的项目的 use() 函数时,例如,m_items.at(i).item->use(*m_player);

它调用基类“Item”use() 函数,而不是“Bandage”use() 函数。

编辑: 这是我的 addItem 函数,

void Inventory::addItem(const Item& item)
{
    if ((m_items.size() < m_capacity))
    {
        bool foundItem(false);
        for (auto invItem : m_items)
        {
            // if the item already exists, lets just increase the quantity
            if (invItem.item->getID() == item.getID())
            {
                foundItem = true;
                if (invItem.quantity < invItem.item->getInventoryQuantityLimit())
                {
                    ++invItem.quantity;
                }
            }
        }

        if (!foundItem){
            m_items.push_back(InventoryItem{ new Item(item), 1 });
        }

    }
}

最佳答案

问题出在您的 addItem() 函数中,更确切地说,这里是:

m_items.push_back(InventoryItem{ new Item(item), 1 });

InventoryItem 中的指针 Item* 最终指向一个 Item,而不是从 Item 派生的对象>,即使 item 派生对象。表达式 new Item(item) 不会创建派生对象,而是调用(默认情况下,如果你没有编写它)复制构造函数 Item 与派生对象item 作为参数。然后它在堆上创建 Item 对象,返回指向它的指针。

使用创建所需项的工厂方法会更好,并摆脱原始指针以支持 std::shared_ptr(或 std::unique_ptr,虽然这里 std::shared_ptr 可能更好)。

关于当我不知道 child 的类型时,C++ 从基类调用子类函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29459893/

相关文章:

c++ - 无法使用scons运行cpp文件

c++ - 装饰者模式 vs. 调用 super 反模式

C#类多态

c# - 从类的基类中捕获异常

c# - 会自动调用基类构造函数吗?

c++ - 我怎样才能从它的多重继承基础中获得一个类地址?

c++ - 将 16 字节 CAS 与 GCC 结合使用时出现未定义的引用链接器错误

C++ 程序读取 '*' 为 'a'

c# - 为什么要实现 IEquatable<T> 接口(interface)

c++ - 抽象类是抽象数据类型的一个例子吗?