2

我使用一个共享指针向量来包含一些称为客户的游戏角色。

typedef std::shared_ptr<Customer> customer;
std::vector<customer> customers;

customers.push_back(customer(new Customer()));

for(int i = 0; i < customers.size(); i++)
{
    if(customers[i]->hasLeftScreen())
    {
        if(!customers[i]->itemRecieved())
            outOfStocks++;
        // Kill Character Here
    }       
}

我以前使用向量来保存对象,所以习惯于在向量上调用擦除并传入迭代器。我的问题是有没有办法从上述代码片段中的向量中删除指针?我希望不要在这里使用迭代器来简化代码。我还需要删除指针,因为我是离开屏幕后要从游戏中删除的客户。

非常感谢

4

3 回答 3

3

考虑使用迭代器,坦率地说,这将更容易处理。我不确定您是否厌恶它们,但请参见下文:

std::vector<customer>::iterator it = customers.begin();
while (it != customers.end())
{
    if(it->hasLeftScreen())
    {
        if(!it->itemRecieved())
            outOfStocks++;
        it = customers.erase(it);
        continue;
    }
    ++it;
}

这将从向量中删除共享指针实例。如果实例是对共享指针的最后引用,它还将释放所述客户的关联内存,触发其析构函数等......(首先使用智能共享指针的意义,以及使用智能指针的道具, 顺便一提)。

于 2013-03-11T16:56:00.853 回答
2

您应该始终使用迭代器;这是一个 C++ 习语。这会将代码更改为...

for(auto i = customers.begin(); i != customers.end(); ++i)
{
    if((*i)->hasLeftScreen())
    {
        if(!(*i)->itemRecieved())
            outOfStocks++;
        // Kill Character Here
    }       
}

现在,很明显,我们改用了erase-remove 习惯用法

int outOfStocks = 0;
auto it = std::remove_if(customer.begin(), customers.end(), [&](Customer const& i) {
    if(i->hasLeftScreen()) {
        if(!i->itemRecieved()) {
            outOfStocks++;
        }
        return true;
    }
    return false;
}
std::erase(it, customers.end());
于 2013-03-11T16:57:41.517 回答
0

您还可以利用“迭代器算术”:

        // Kill Character Here
        customers.erase(customers.begin() + i);

...但这有一个问题,customers.size()当前索引将随着容器缩小而失效。

此外,您不需要明确指出delete要删除的客户,因为智能指针会处理这些问题。

于 2013-03-11T17:00:21.953 回答