13 июля 2006

delete this

Конструкция delete this; выглядит довольно необычно. Выглядит, как будто мы рубим сук, на котором сидим. Однако, все довольно безопасно, если выполнять меры предосторожности (мыть руки перед едой ;)).

Что из себя представляют методы класса? Да это обычные функции, которым неявно передается указатель this.

void vector::remove(ItT it)
на самом деле выглядит примерно как
void ::remove(vector* this, ItT it)

Кстати, int vector::size() const
выглядит как int ::size(const vector* this).

Соответственно, внутри метода можно спокойно удалить какой-то объект, а называется он this или как-то по-другому - это все равно. Главное, не пользоваться этим объектом после удаления. Причем (внимание!) нужно перестать им пользоваться совсем, то есть не только в этом методе после выполнения delete this;, но и там, откуда этот метод вызван.

Но это еще не все предосторожности. Перед тем как сделать delete this; естественно надо убедиться, что объект создан через new, а не на стеке или еще как-то (каким-нибудь нестандартным аллокатором). Как убедиться в этом - вопрос дизайна (design). Можно просто написать в документации: "этот объект нужно создавать через new" или сделать конструкторы приватными и создат static-member-ов для создания объектов. Или вообще использовать boost:shared_ptr, и тогда вместо delete this; будет sp.release(), который удалит объект как ему предписывает назначенный deleter.

Ссылка по теме: ATL's CWindowImpl::OnFinalMessage() crash

2 комментария:

Анонимный комментирует...

"который объект как ему предписывает назначенный deleter" -- missing word?

Raider комментирует...

thanks! fixed