0

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

在标题中,我有这个:

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

在.cpp中我这样做:

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

Circle的子类在哪里Obstacle

我的问题是我应该什么时候调用delete向量中的元素?我听说每个都new应该用一个来平衡delete。我是否需要在析构函数中循环遍历向量并调用delete每个元素?没有更优雅的方式吗?

谢谢

4

3 回答 3

10

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

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

当然,以上所有这些都是假设您确实有充分的理由使用指针。通常最好的解决方案是最简单的:按价值持有物品:

std::vector<SomeType> things;

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

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

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);
于 2012-10-14T09:15:36.940 回答
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!
 }
于 2012-10-14T11:05:40.557 回答
-1

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

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

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

什么都没有new,什么都不需要delete,你节省了内存分配,访问存储在向量中的对象变得更有效率。

此外,您的代码不会再让更有经验的 C++ 开发人员眼花缭乱。

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

于 2012-10-14T09:17:00.317 回答