【问题标题】:Using delete on pointers in a a vector对向量中的指针使用删除
【发布时间】:2017-09-01 22:48:58
【问题描述】:

我是一名业余程序员,正在通过尝试在控制台上制作文本角色扮演游戏来学习。我现在只是想考虑如何设计我的代码,而我却被困在物品和库存类如何协同工作上。我有这样定义的库存类:

class Inventory {
private:
    vector<Item*> items;

public:
    Inventory() {
        items.resize(10);
        for (int i = 0; i < 10; ++i) {
            items[i] = nullptr;//so I can still display an empty inventory
        }
    };
    ~Inventory() {
        for (int i = 0; i < 10; ++i) {
            delete items[i];
        }
    }

    void AddItem(Item* item) {
        for (int i = 0; i < items.size(); ++i) {
            if (items[i] == nullptr) {//if the slot is empty
                items[i] = item;
                break;
            }
        }
    }

    void Show() const {
        for (int i = 0; i < items.size(); ++i) {
            cout << "Slot " << i + 1 << ": ";
            if (items[i] == nullptr) {
                cout << "<Empty Slot>" << endl;
            } else {
                cout << "<" << items[i]->GetName() << ">" << endl;
            }
        }
    }
};

最终我打算让敌人在死后掉落战利品,所以我需要使用new 创建物品,然后将它们转移到玩家的库存中。我的问题是,我应该只了解智能指针并使用它们,还是我在这里调用 delete 的方式可以还是完全愚蠢?还是我应该以不同的方式考虑这个代码结构?谢谢你的回答,如果你这样做了!我真的很感激。

【问题讨论】:

  • 首选方式是std::vector&lt;Item&gt;,而不是null 条目。如果你真的需要指针,那么std::vector&lt;std::unique_ptr&lt;Item&gt;&gt;
  • @ZekeWillams 虚拟派生确实是使用指针的原因,但即便如此,也不是原始指针。使用智能指针和proper RAII concepts.
  • 如果库存永远不会改变大小,请查看std::array。这是一个更智能的固定大小数组。
  • 如果库存大小可能是动态的,那么像std::vector 这样的动态容器就可以了。关于std::optional 是/做什么,你可以read about std::optional here。它是 C++17 的一部分,因此您的工具链可能不符合使其成为...的选项(可怜的双关语无意)。

标签: c++ oop vector game-engine inventory


【解决方案1】:

正确的方法是使用迭代器。不要在

中传递'Item'的指针

void AddItem(Item* item) 方法。

您应该创建一个“Item”类的迭代器并将该迭代器传递给“AddItem”方法。类似地,创建另一个方法“RemoveItem”,该方法返回一个“Item”的迭代器,该迭代器可以发送到 Player 的“CollectMoney”方法。

如果您不想使用迭代器,您也可以使用“Item * item”,但您必须调用方法“RemoveItem”来获取“Item”的引用,以便将其传递给 Player。由于项目不是在类中创建的,因此不应在类中删除它们,因此请删除析构函数。

PS 使用这个构造函数 -> Inventory() {items.resize(10,nullptr);}

【讨论】:

  • 在我能找到的所有与我有类似问题的帖子中,我从未见过有人提到这一点。您将如何使用它?我将如何声明这样的迭代器以及在哪个类中?谢谢你的回答。
  • 然后按照上面的说明,将指针指向“Item”,删除析构函数并添加“RemoveItem”方法。保持一致。您可以了解迭代器。它们提供封装。这是一个示例迭代器:gist.github.com/jeetsukumaran/307264
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-04-28
  • 1970-01-01
  • 2013-09-24
  • 2012-08-12
  • 2015-08-09
  • 1970-01-01
相关资源
最近更新 更多