库存系统中的对象切片
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);
我正在为一款游戏开发库存系统,但我遇到了对象切片问题;我正在丢失对派生 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);