Что произойдет, если вы удалите это в С++
Возможный дубликат:
Можно ли использовать "удалить это" для удаления текущего объекта?
Я только что увидел некоторый код, в котором они выполнили delete this;
в функции класса, я знаю, что это не очень хороший дизайн, но он определил, что произойдет, скажем, что класс всегда является указателем откуда-то. Будет ли он всегда удален правильно?
class A
{
public:
void abort() { delete this; }
};
class B
{
void func() { A* a = new A; a->abort(); }
};
Ответы
Ответ 1
Это совершенно законно в С++ до delete this
и на самом деле очень полезно для определенных шаблонов, таких как интеллектуальные указатели. Бремя лежит на разработчике, но для того, чтобы убедиться, что другие методы не вызываются или в стеке для this
, которые будут обращаться к данным экземпляра после удаления.
В С++ FAQ Lite есть запись для этого, которая стоит прочитать
Ответ 2
Это не тот случай, когда delete this;
плохой дизайн, и это определенно не приводит к поведению undefined. Он делает то, что вы ожидаете - он удаляет этот объект. Это означает, что вам лучше убедиться, что вы ничего не делаете с объектом после того, как был вызван delete this
.
В классах Microsoft MFC широко используется delete this;
, например, в классе CWnd (window). Когда окно получает сообщение WM_DESTROY, класс оболочки окна (то есть объект С++) больше не нужен, поэтому он вызывает delete this;
(я думаю, в PostNcDestroy()
, где-то в этом роде). Это очень удобно с точки зрения пользователя фреймворка: вам просто нужно помнить, что есть способы, чтобы объект С++ автоматически удалялся и немного осторожно приближался к концу жизненного цикла окна.
Я уверен, что есть много других реальных примеров, где delete this;
- полезная парадигма.
Ответ 3
Да. Вам остается только позаботиться о том, чтобы после оператора delete
не использовалась никакая переменная экземпляра (и, как мне кажется, не виртуальный метод), поскольку указатель this
больше не будет действителен после delete
.
Ответ 4
да, его следует удалить обычно.
Есть несколько случаев, когда это полезно, но необходимо проявлять особую осторожность, чтобы быть уверенным, что после этого объект никогда не будет доступен.
Ответ 5
Как было отмечено комментатором, нет поведения undefined, если после удаления других членов
Вы сможете продолжить эту функцию, если вы не получите доступ к другим членам объекта.
Ответ 6
В этом конкретном случае это нормально, но подумайте, что произойдет, если a
- автоматическая переменная:
void foo() {
A a;
a.abort(); // BOOM!
}