我是C ++的新手,对内存管理有疑问。
在标题中,我有这个:
std::vector<Obstacle::Obstacle*> obstacles;
在.cpp中我这样做:
Circle *circle = new Circle(x, y, radius);
obstacles.push_back(circle);
其中Circle
是Obstacle
的子类。
我的问题是我应该何时在向量中的元素上调用delete
?我听说每个new
应该由delete
平衡。我是否需要在析构函数循环中遍历向量并在每个元素上调用delete
?是不是有更优雅的方式?
由于
答案 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 ++开发人员流眼泪。
总而言之,我称之为胜利。 :)