从std :: vector中删除动态分配的对象

时间:2011-03-26 21:36:07

标签: c++ vector

这是对的吗?:

std::vector<Enemy*> enemies;
enemies.push_back(new Enemy());

Enemy* enemy = enemies[0];
enemies.erase(enemies.begin() + 0);
delete enemy;

4 个答案:

答案 0 :(得分:8)

它有效,是的,但这不是一种理想的方法。

首先,添加0只是噪音,你可以删除它。但更好的是,只需使用pop_front()即可。此外,不需要中间步骤,您可以在删除之前删除。

但是std::vector从前面弹出并不好,特别是如果它很大(因为剩下的元素需要移动以填补空白)。如果您不需要连续内存,请改用std::deque。或者,如果订单无关紧要,您可以使用以下内容:

template <typename T, typename A>
void unordered_pop_front(std::vector<T, A>& vec)
{
    using std::swap;
    swap(vec.front(), vec.back()); // constant time

    vec.pop_back(); // constant time
}

它将前部元素与后部元素交换,然后将其弹出。当然,订单不会保留。

另一个问题是你的内存管理方法。任何时候你有明确的清理代码,你做错了什么。它应该是done automatically

使用Boost's ptr_vectorsmart pointersstd::vector。 (注意:不要在容器中使用std::auto_ptr,在这方面它是坏的。)对于快速智能指针建议,使用std::unique_ptr(如果您的编译器支持C ++ 0x)或{{ 1}}。

答案 1 :(得分:4)

std::vector<Enemy*> enemies;
enemies.push_back(new Enemy());

这不是例外安全的。如果push_back无法分配足够的内存来容纳新指针,那么Enemy对象就会泄露。

使用智能指针向量可以解决这个问题,但是在推回之前你应该保留向量中的空间:

std::vector<Enemy*> enemies;
enemies.reserve(1);    // or more generally, enemies.reserve(enemies.size()+1);
enemies.push_back(new Enemy());

现在我们知道push_back无法分配内存,如果reserve失败,则在创建Enemy之前抛出异常。

答案 2 :(得分:2)

当然看起来很好。您不需要+ 0行中的enemies.erase,但除此之外,它完全没问题。

答案 3 :(得分:1)

是的,没关系。您可以稍微简化一下:

delete enemies[0];
enemies.clear();

要删除元素,您还可以使用:

enemies.pop_back();

或(与你的非常相似):

enemies.erase(enemies.begin());