库存系统中的对象切片

Object slicing in Inventory system

我正在为一款游戏开发库存系统,但我遇到了对象切片问题;我正在丢失对派生 class 的引用的变量。 以下是在主游戏文件中创建 T 恤的摘录,然后传递到玩家库存进行存储。但是,仅保留基数 class Item 中存在的变量。

game.cpp

#include "Item.h"
#include "Clothes.h"
#include "Shirts.h"

shirt_item white_shirt = shirt_item(materialDescriptor::cotton, colourDescriptor::white);

player.getComponent<InventoryComponent>().storeItem(&whiteShirt);

InventoryComponent.cpp

bool InventoryComponent::storeItem(Item *inItem)
{
    if (freeInvSpace() > 0)
    {
        items.push_back(inItem);
        return true;
    }
    else if (freeInvSpace() < 0)
    {
        std::cout << "ERROR! Inventory over filled somehow" << std::endl;
    }

    return false;
}

InventoryComponent.h

#pragma once
#include "Components.h"

#include "Item.h"
#include "Clothes.h"
#include "Shirts.h"



class InventoryComponent : public Component // Entity component system
{
public:
    std::vector<Item*> items;

   InventoryComponent(int inSize)
    {
        size = inSize;
    }

    bool storeItem(Item *inItem);
...
}

Item.h

#pragma once
#include <string>

class Item
{
public:
    std::string name,
        description;

    bool pronoun;
};

Clothes.h

#pragma once
#include <vector>
#include <string>

#include "Item.h"
#include "materialDescriptor.h"
#include "colourDescriptor.h"

class Clothes : public Item
{
public:
    materialDescriptor material;
    std::vector<bodyParts> coverage;
    colourDescriptor colour;

    Clothes(std::string inName, std::string inDescription, materialDescriptor inMaterial, colourDescriptor colour, bool inPronoun = false)
    {
        name = inName;
        description = inDescription;
        material = inMaterial;
        pronoun = inPronoun;
    }

    Clothes() {} 
};

Shirts.h

#pragma once
#include "Clothes.h"
#include "materialDescriptor.h"
#include "colourDescriptor.h"

class shirt_item : public Clothes
{
public:
    shirt_item(materialDescriptor inMaterial, colourDescriptor inColour)
    {
        material = inMaterial;
        colour = inColour;
        description = "A basic shirt that covers the wearer from the elements";
        name = "T-Shirt"
    }
}

ECS.h

#pragma once
#include <iostream>
#include <vector>
#include <memory>
#include <algorithm>
#include <bitset>
#include <array>

#include "Components.h"

class Component
{
public:
    Entity* entity;

    virtual void init() {}
    virtual void update() {}
    virtual void draw() {}

    virtual ~Component() {}

private:
};

class Entity
{
private:
    bool active = true;
    std::vector<std::unique_ptr<Component>> components;

    ComponentArray componentArray;
    ComponentBitSet componentBitSet;

public:
    template <typename T> T& getComponent() const
    {
        auto ptr(componentArray[getComponentTypeID<T>()]); 
        return *static_cast<T*>(ptr);
    }
}

使用 Vs2019 断点,T 恤的构造函数可以工作,但一旦我尝试使用该对象,它就会被归结为它的基础 class:Item > 衣服 > 衬衫

如果您通过指针传递和存储继承的对象,您最终必须将它们存储在堆上。相反,您是在堆栈上创建它们。就这样
auto white_shirt = std::make_unique<shirt_item>(materialDescriptor::cotton, colourDescriptor::white);