Объектно-ориентированное самоубийство или удалить это; - PullRequest
10 голосов
/ 18 октября 2010

Следующий код, скомпилированный с MSVC9.0, запускается и выводит Destructor четыре раза, что логично.

#include <iostream>
class SomeClass
{
public:
   void CommitSuicide()
   {
      delete this;
   }
   void Reincarnate()
   {
      this->~SomeClass();
      new (this) SomeClass;
   }
   ~SomeClass()
   {
      std::cout  << "Destructor\n";
   }
};

int main()
{
   SomeClass* p = new SomeClass;
   p->CommitSuicide();
   p =  new SomeClass;
   p->Reincarnate();
   p->~SomeClass(); //line 5
   p->CommitSuicide();
}

Я думаю, что первые 4 строки кода в main не приводятв неопределенном поведении (хотя и не совсем уверен насчет delete this;).Я хотел бы получить подтверждение или <заполнитель для антонима подтверждения> этого.Но у меня есть серьезные сомнения по поводу строк 5 и 6. Разрешается явно вызывать деструктор, не так ли?Но считается ли срок службы объекта законченным после этого?То есть разрешен ли (вызван) вызов другого члена после явного вызова деструктора?

Подводя итог, какие части приведенного выше кода (если таковые имеются) приводят к неопределенному поведению (технически говоря)?

Ответы [ 3 ]

6 голосов
/ 18 октября 2010

delete this; в порядке. Последний p->CommitSuicide(); дает неопределенное поведение, потому что вы уже уничтожили объект в «строке 5».

2 голосов
/ 18 октября 2010

p-> ~ SomeClass ();// строка 5

p-> CommitSuicide ();// строка 6

Line (6) определенно вызывает неопределенное поведение.

То есть, разрешен (определен) вызов другого члена после явного вызова деструктора?

Нет!Ваше предположение верно.

0 голосов
/ 18 октября 2010

«Удалить это» нормально, если вы не пытаетесь вызвать какой-либо код этого объекта после удаления (даже деструктора). Таким образом, самоуничтожающийся объект должен быть помещен только в кучу, и у него должен быть личный деструктор для защиты от создания в стеке.

Я не знаю, приведет ли прямой вызов деструктора к неопределенному поведению, но пользовательский оператор удаления не будет выполнен.

...