如何使主机库存系统具有动态性

How to make a console inventory system dynamic

本文关键字:动态性 系统 何使 主机      更新时间:2023-10-16

我有一个存储"Item"类型的库存系统,这是一个抽象类。我有一个派生类叫做"Skates"。该程序允许用户将"Skates"添加到"Item"指针的向量中。用户输入冰鞋的型号和ID,然后我用这些作为参数创建一个"skates"对象。然后我使用"Item"指针指向"Skates"对象并将其添加到向量中。当用户想要编辑"Skates"对象时,我必须将其动态转换回"Skates"对象,然后编辑它。

std::vector<Item*> ItemCollection;
Item * item = new Skates("model1", 1);
ItemCollection.push_back(item);
//To retrieve it
Skates * skatesToEdit = dynamic_cast<Skates*>(ItemCollection[0]);

我现在面临的问题是考虑一个新的派生类,例如"Skateboard"类。我不想创建一个新方法来处理"Skateboard"类的编辑,如:

Skateboard * skateboardToEdit = dynamic_cast<Skateboard*>(ItemCollection[0]);

因为这意味着每次我创建一个新的派生类时,我都需要每次都编写相同风格的代码。所以我想知道是否有一种方法可以使应用程序动态地知道它是什么派生类,而不需要我指定它。因此,它需要能够确定数据类型,然后提示用户编辑它所拥有的任何属性(因为目标是让用户首先编辑对象)在一个动态方法中,我认为这应该是不可能的。

我认为继承可能不是您在这里需要的。与其拥有像Skates, Skateboard这样的类,不如考虑只拥有类Item,它是表示属性的键值的集合。这样你就不用关心项目的类了,你可以动态地列出和编辑属性。

据我所知,您有编辑派生项的方法,如void editSkates(Skates*), void editSkateboard(Skateboard*)等。

则可以应用访问者模式。用visit方法创建抽象的Visitor类,为每个不同的Item子类重载:

class ItemVisitor{
public:
    virtual void visit(Skates*) = 0;
    virtual void visit(Skateboard*) = 0;
    //... one function for every subclass
};

Item类中创建virtual void accept(ItemVisitor&) = 0;方法在每个子类(例如Skates)中,重写此方法以调用正确的visit:

void Skates::accept(ItemVisitor& visitor){
    visitor.visit(this);
}

现在你可以继承ItemVisitor,用特定的子类做特定的事情,像这样:

class EditVisitor: public ItemVisitor{
public:
    virtual void visit(Skates* skates){
        skates->editSpecialSkatesProperty();
    }
    virtual void visit(Skateboard* skateboard){
        skateboard->editSpecialSkateboardProperty();
    }
};

最后用你的通用Item * item实例做这个特定的事情:

EditVisitor edit;
item->accept(edit);