Удалить это? Что это делает?
Учитывая следующее:
#include <iostream>
using namespace std;
class A
{
public:
void func() {delete this;}
A() : x(5) {cout << "ctor A" << endl;}
~A() {cout << "dtor A" << endl;}
int x;
};
int main() {
A a;
cout << "The X value: " << a.x << endl;
a.func(); // calling 'delete this' ->going to the dtor #1
cout << "The X value: " << a.x << endl;
return 0;
}
выход:
ctor A
The X value: 5
dtor A
The X value: 5
dtor A
Есть ли delete this;
имеет какие-либо радикальные последствия?
5 ответов
В этом случае (вы не выделяли объект A с помощью new) вы вызываете неопределенное поведение. Неопределенное поведение обычно очень и очень плохо. В принципе, все может случиться.
Можно написать код, где "удалить это;" было бы хорошо, хотя Но я не могу вспомнить, чтобы когда-либо делал это. Постарайся избежать этого. Старайтесь избегать вызова delete вручную (независимо от того, использовали ли вы новый или нет), передав эту ответственность другому объекту (например, интеллектуальному указателю).
delete
оператор вызывает деструктор объекта, а затем освобождает основную память, используемую объектом. Память должна быть выделена new
оператор. В delete this
удаленный объект является просто текущим объектом. В конструкции нет ничего особенного, это просто C++.
В вашем примере память из стека, и, таким образом, вы входите в область неопределенного поведения (так как вы вызываете delete
оператор на объекте, который не был выделен через new
оператор).
Обычно считается плохой дизайн, чтобы позвонить delete this
потому что объект не должен нести ответственность за свою жизнь. Обычно считается наилучшей практикой привлекать создателя объекта к ответственности за его уничтожение.
Однако есть одна ситуация, когда я лично нахожу это действительно полезным. Это происходит, когда вы общаетесь с помощью сообщений. В этом случае, если сообщение отвечает за свой собственный срок жизни, его на самом деле безопаснее и легче написать, чем за него отвечает оригинальный поток.
Я посмотрю мимо того, что ты звонишь delete
на выделенном стеке объекте, и изучите использование delete this
в общем.
Существует школа мысли, которая говорит: "Это не очень хорошая идея". Однако я видел, как он несколько раз использовался с реализациями объектов с подсчетом ссылок.
В COM платформа требует, чтобы все объекты были созданы фабричным методом, а затем снова выпущены при вызове "Release".
class MyRefCountedObject : public IUnknown
{
private:
// Making the constructor and destructor private
// so that the object can only be allocated as a pointer
MyRefCountedObject() {}
~MyRefCountedObject() {}
MyRefCountedObject(const MyRefCountedObject& mrco) {}
int _refCount;
public:
static MyRefCountedObject* CreateInstance()
{
MyRefCountedObject* pObject = new MyRefCountedObject();
pObject->_refCount = 1;
return pObject;
}
void Release()
{
if(--_refCount == 0)
{
delete this;
}
};
void AddRef()
{
++_refCount;
}
}
Обратите внимание - это не полная реализация, а просто представление о логике. Но, сделав конструктор частным, я могу гарантировать, что это когда-либо будет размещено только в куче.
C++ FAQ Lite: "Законно ли (и морально) для функции-члена сказать" удалить это "?"
Тем не менее, вы должны редко, если когда-либо использовать это в правильно организованном коде.
Вы не должны этого делать. Это плохая практика программирования. Объект, который использует new, должен быть объектом, который использует delete. В противном случае вы попадете в беспорядок и в конечном итоге с утечками памяти и т.д.