Объектно-ориентированное самоубийство или удалить это;

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

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

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 ответов


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

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

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

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

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


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


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

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