何时删除添加到std :: vector的元素?

时间:2012-10-14 09:13:00

标签: c++

我是C ++的新手,对内存管理有疑问。

在标题中,我有这个:

std::vector<Obstacle::Obstacle*> obstacles;

在.cpp中我这样做:

Circle *circle = new Circle(x, y, radius);
obstacles.push_back(circle);

其中CircleObstacle的子类。

我的问题是我应该何时在向量中的元素上调用delete?我听说每个new应该由delete平衡。我是否需要在析构函数循环中遍历向量并在每个元素上调用delete?是不是有更优雅的方式?

由于

3 个答案:

答案 0 :(得分:10)

在清除向量之前,或者在向量超出范围之前,必须在元素上调用delete 如果向量拥有指向的对象。更优雅的解决方案是让向量保持smart pointers。特定类型的智能指针应取决于所有权策略。 例如,拥有指向对象的向量应使用C ++ 11 std::unique_ptr

std::vector<std::unique_ptr<Obstacle>> obstacles;

当然,以上所有都假设你实际上有充分的理由使用指针。通常最好的解决方案是最简单的解决方案:按值保存项目:

std::vector<SomeType> things;

请注意,这不适用于您存储指向从基类派生的对象的指针的情况,因为存储基类型的值将导致object slicing

编辑:当向量超出范围时,确保删除元素的一种简单方法是编写范围保护类:

template <typename CONTAINER>
struct PtrContainerGuard
{
  PtrContainerGuard(CONTAINER& container) : c_(container) {}
  ~PtrContainerGuard()
  {
    for (typename CONTAINER::iterator it = c_.begin(); it != c_.end(); ++it)
      delete (*it);
  }
private:
  CONTAINER& c_;

}

然后

std::vector<Obstacle*> obstacles;
PtrContainerGuard<std::vector::Obstacle*> p(obstacles);

答案 1 :(得分:0)

为什么不使用shared_ptr?您不必创建新对象,并担心在使用它们时将其删除。

typedef shared_ptr<Obstacle> ObstaclePtr;
int main()
{
std::vector<ObstaclePtr> obstacles;
//Create objets using shared_ptr and push them in vector
ObstaclePtr obstacle1(new Circle());
obstacles.push_back(obstacle1);

ObstaclePtr obstacle2(new Circle());
obstacles.push_back(obstacle2);
//When vector obstacles goes out of scope here, all circles inside are destructed!
 }

答案 2 :(得分:-1)

是的,有一种更优雅的方式。扔掉你所有的指针。

std::vector<Obstacle::Obstacle> obstacles;

Circle circle(x, y, radius);
obstacls.push_back(circle);

没有new编辑,没有必要delete d,您保存了内存分配,并且对存储在向量中的对象的访问变得更有效。

此外,您的代码将不再让更多有经验的C ++开发人员流眼泪。

总而言之,我称之为胜利。 :)