删除包含其他实例的实例的运算符

时间:2014-08-25 15:48:55

标签: c++

我有关于删除操作符的问题。如果有3个实例,每个实例都持有下一个/上一个实例,如何删除它?

class A : public Parent
{
privte:
  A* next;
  A* previous;
public:
  void setNext(A*);
  void setPrevious(A*);
};

.. 
int main()
{
  A* obj1 = new A();
  A* obj2 = new A(); 
  A* obj3 = new A();

  obj1->setNext(obj2);
  obj2->setNext(obj3);
  obj3->setNext(nullptr);

  obj1->setPrevious(nullptr);
  obj2->setPrevious(obj1);
  obj3->setPrevious(obj2);

  return 0;
}

如果我删除obj1 .. obj2和obj3自动删除。为什么?这是内存泄漏吗?他们真的被删除了吗?我不明白这种行为。每个新的都不应该删除吗?

1 个答案:

答案 0 :(得分:1)

您必须考虑资源所有权问题。你做出了一些政策决定。然后编写确认该政策的代码。

执行后:

obj1->setNext(obj2);

谁拥有obj2obj2拥有obj1?它是由调用函数还是更高级别的对象拥有的?

如果您的政策说明obj1拥有obj2,那么您在删除obj2时必须删除obj1

如果您的政策说调用函数或更高级别的对象拥有obj2,则删除obj2时不得删除obj1

你问:

  

如果我删除obj1 .. obj2和obj3自动删除。为什么呢?

因为您没有编写删除它们的代码。

  

这是内存泄漏吗?

  

它们真的被删除了吗?

没有

  

我不明白这种行为。每个新的都不应该删除吗?

是。应该。但是,您必须确保从delete返回的每个对象都调用new

如果您的政策是obj1在上述电话会议后拥有obj2,则您必须实施A的析构函数才能删除nextprevious 。但是,在执行此操作之前,必须确保正确处理链接。否则,您将遇到已被删除的指针,如果您没有正确处理链接,则会遇到内存泄漏。

~A()
{
   // Hopefully next->previous points to this.
   // You have to unlink next from this. Otherwise, 'delete next' will end up calling
   // delete on 'this`.
   // Similarly with previous

   if ( next != nullptr )
   {
       next->previous = nullptr;
      delete next;
   }

   if ( previous!= nullptr )
   {
       previous->next= nullptr;
      delete previous;
   }
}

您仍然需要致电

delete obj1;
main

以确保删除所有对象。

如果您的策略是调用函数或更高级别的对象在语句后拥有objt2

obj1->setNext(obj2);

你必须在调用函数的所有对象上调用delete。

int main()
{
  A* obj1 = new A();
  A* obj2 = new A(); 
  A* obj3 = new A();

  obj1->setNext(obj2);
  obj2->setNext(obj3);
  obj3->setNext(nullptr);

  obj1->setPrevious(nullptr);
  obj2->setPrevious(obj1);
  obj3->setPrevious(obj2);

  delete obj3;
  delete obj2;
  delete obj1;

  return 0;
}

为了使它更清洁,你应该处理一个类似于std::list的更高级别的容器。您可以在列表中添加和删除项目。删除列表时,必须确保删除所有包含的元素。