简体   繁体   中英

Object slicing in Inventory system

I'm working on an inventory system for a game and I'm hitting a brick wall with object slicing; I'm losing variables on a reference to a derived class. Below is an excerpt in which a T-shirt is created in the main game file, and then passed to a players inventory for storage. However only the variables present in the base class Item are preserved.

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);
    }
}

Using Vs2019 break points, the constructor for the T-shirt works but as soon as I attempt to use the object it is boiled down to it's base class: Item > Clothes > Shirts

If you pass and store inherited objects through pointers you eventually have to store them on the heap. Instead you are creating them on the stack. Just do
auto white_shirt = std::make_unique<shirt_item>(materialDescriptor::cotton, colourDescriptor::white);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM