带有自定义对象的C ++数组

时间:2014-01-21 16:14:28

标签: c++ arrays

搜索谷歌和stackoverflow 2天后,我还没有找到任何东西

我正在使用Java大约一年,我决定用C ++创建一个游戏练习

在java中,这应该可行,但在C ++中它会让我大吃一惊。

我有这段代码

Item* inventory = new Item[24];

它是保存物品的数组(库存)

当我动态分配数组时,它的所有位置都为空? 如果没有,我可以将它们全部归零吗?

这就是在第一个空位置添加物品的代码(拿起物品)

void Inventory::addItem(Item it){
    if(isFull()){
        cout << "Full inventory" << endl;
    }else{
        for(int i = 0; i<length; i++){
            if(inventory[i] == nullptr){ // need this to work somehow
                  inventory[i] = it;
            }
        }
    }
}

它必须是数组而不是矢量,因为它具有固定的大小

2 个答案:

答案 0 :(得分:5)

  

当我动态分配数组时,它的所有位置都为空?如果没有,我可以将它们全部归零吗?

在C ++中没有像null那样的东西,就像在Java中一样。相反,您可以使用nullptr指针。在您的情况下,对象是默认构造的,因此不是null。

  

它必须是数组而不是矢量,因为它具有固定的大小

除非绝对必要,否则您通常不希望动态分配。如果你真的想要一个固定大小的数组,请使用std::array

我建议将std::arraystd::unique_ptr结合使用:

std::array<std::unique_ptr<Item>, 24> arr;

默认情况下,所有std::unique_ptr都是nullptr。当你需要分配一个对象时,你将能够做到:

arr[i] = std::unique_ptr<Item>(new Item(...));

您甚至可以为智能指针创建别名:

using item_ptr = std::unique_ptr<Item>;

这将帮助您将代码重写为:

std::array<item_ptr, 24> arr;
arr[0] = item_ptr(new Item(...));

或者您也可以使用boost::optional(或来自C ++ 14的std::optional):

std::array<std::optional<Item>> arr;

您将能够检查特定i元素是否为“null”(在Java意义上):

if (arr[i])
    // not null

您将能够使用以下内容分配值:

arr[i] = Item(...);

并使用*arr[i]arr[i]->member_function(...);arr[i]->member_object检索它。

答案 1 :(得分:2)

与您的最终评论相反,这似乎是std::vector的完全合理的应用。

现在看来,你正在尝试创建一个N个对象的数组,但是其中有一些M实际上是空/空/不存在的对象。

现实情况是,根本不是固定大小的集合。它是一个可变大小的集合,达到某个指定的最大值。在给定的时间,玩家可能携带1件物品或10件物品,但他们可携带的物品数量最多。然而,他们,不断携带最大数量的物品,其中一些恰好是空物品 1

由于您正在处理的是一个可变大小的集合(达到指定的最大值),std::vector完全适合该法案。由于您正在处理Item类,因此假设实际项目是来自Item的具体类的实例可能是合理的。在这种情况下,你真的需要在数组中存储(某种各样的)指针,而不是实际的Item对象(否则,你尝试放入数组的每个派生项都将是&#34;切片&#34;成为一个实际的Item对象,而不是派生对象,当它存储在数组中时。)

可以通过创建unique_ptr s(或其他各种其他智能指针类型,例如shared_ptr)的集合来实现这一点,但我<\ n < em>通常建议在这种情况下,您可以考虑使用Boost ptr_vector类型。

就强制执行大小限制而言,您可能希望创建一个小的包装类来处理它。这不是一项复杂的任务,但将代码集中在一个地方显然更好,而不是在可能将项目添加到库存的任何地方重复大小检查代码。

template <class T>
class inventory { 
    ptr_vector<T *> items;
    size_t max;
public:
    inventory(size_t max) : max(max) {}
    push_back(T *t) { 
        if (items.size() < max)
            items.push_back(t);
    }

    // other miscellany here.
};

但是,您 的可能性是Item s的多态层次结构。相反,您只有一个固定类型的库存中的所有项目,每个项目都有一个名称等。如果是这种情况(即,所有Item s实际上是同一类型的对象),那么就没有理由搞乱指针或ptr_vector。你真的只想要std::vector<Item>。与上述情况类似,您无疑仍然希望集中代码以强制实施库存的最大规模(并且可能还提供其他特定于库存的服务)。


  1. 如果你允许我一个题外话,那么有人甚至会考虑这种可能性的事实表明,使用Java的程度会扭曲人们的思维并破坏他们清晰思考的能力。用Dijkstra来解释,教Java应该是一种刑事犯罪。