C++ “删除这个”是否安全?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/550189/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is it safe to `delete this`?
提问by Cristián Romo
In my initial basic tests it is perfectly safe to do so. However, it has struck me that attempting to manipulate this
later in a function that delete
s this
could be a runtime error. Is this true, and is it normally safe to delete this
? or are there only certain cases wherein it is safe?
在我最初的基本测试中,这样做是完全安全的。然而,它已经让我吃惊试图操纵this
后来在一个函数,delete
小号this
可能是一个运行时错误。这是真的delete this
吗,通常安全吗?还是只有某些情况下它是安全的?
回答by Chris Peterson
delete this
is legal and does what you would expect: it calls your class's destructor and free the underlying memory. After delete this
returns, your this
pointer value does notchange, so it is now a dangling pointer that should notbe dereferenced. That includes implicit dereferencing using the class's member variables.
delete this
是合法的,并且符合您的预期:它调用您的类的析构函数并释放底层内存。之后delete this
的回报,你的this
指针值并没有改变,所以它现在是一个悬摆指针应该不会被取消引用。这包括使用类的成员变量隐式取消引用。
It is usually found in reference-counted classes that, when the ref-count is decremented to 0, the DecrementRefCount()
/Release()
/whatever member function calls delete this
.
它通常是在引用计数类发现,当REF-计数递减到0时,DecrementRefCount()
/ Release()
/不管成员函数调用delete this
。
delete this
is typically considered very bad form for many reasons. It is easy to accidentally access member variables after delete this
. Caller code might not realize your object has self-destructed.
delete this
由于多种原因,通常被认为是非常糟糕的形式。之后很容易意外访问成员变量delete this
。调用方代码可能没有意识到您的对象已自毁。
Also, delete this
is a "code smell" that your code might not have a symmetric strategy for object ownership (who allocates and who deletes). An object could not have allocated itself with new
, so calling delete this
means that class A is allocating an object, but class B is later freeing it[self].
此外,delete this
还有一种“代码味道”,即您的代码可能没有对象所有权的对称策略(谁分配和谁删除)。一个对象不能用 分配自己new
,所以调用delete this
意味着类 A 正在分配一个对象,但类 B 稍后释放它[self]。
回答by JaredPar
It's safe to delete "this" as long as it's essentially the last operation in the method. In fact several professional level APIs do so (see ATL's CComObject implementation for an example).
删除“this”是安全的,只要它本质上是方法中的最后一个操作。事实上,一些专业级别的 API 是这样做的(参见 ATL 的 CComObject 实现示例)。
The only danger is attempting to access any other member data after calling "delete this". This is certainly unsafe.
唯一的危险是在调用“删除此”后尝试访问任何其他成员数据。这当然是不安全的。
回答by JaredPar
but dont do it in the destructor !
但不要在析构函数中这样做!
回答by 1800 INFORMATION
Delete this is perfectly legal as others have already mentioned. It is risky for one additional reason that hasn't been mentioned yet - you are assuming that the object has been allocated on the heap. This can be difficult to guarantee, although in the case of reference counting implementations isn't generally a problem.
正如其他人已经提到的那样,删除这是完全合法的。由于尚未提及的另一个原因,这是有风险的 - 您假设对象已在堆上分配。这可能很难保证,尽管在引用计数实现的情况下通常不是问题。
回答by Bruce Ikin
As stated by others, delete this is a valid idiom but for it to be safe you have to ensure that the object is never instantiated on the stack.
正如其他人所说,删除这是一个有效的习惯用法,但为了安全起见,您必须确保该对象永远不会在堆栈上实例化。
One way to do this is to make both the constructor and the destructor private and enforce object creation through a class factory function which creates the the object on the heap and returns a pointer to it. The class factory can be a static member function or a friend function. Cleanup can then be done through a Delete() method on the object that does the "delete this". COM objects basically work this way except that in addition they are reference counted with the "delete this" occurring when the reference count is decremented to zero.
一种方法是将构造函数和析构函数都设为私有,并通过类工厂函数强制创建对象,该函数在堆上创建对象并返回指向它的指针。类工厂可以是静态成员函数或友元函数。然后可以通过执行“删除此”的对象上的 Delete() 方法完成清理。COM 对象基本上以这种方式工作,除了当引用计数递减为零时,它们会通过“删除此”进行引用计数。
回答by rptony
delete this can cause an issue when you have subclasses of the object you are deleting. Remember construction starts from top down and deletion starts from bottom up. So if delete this is in the middle of the hierarchy you basically lost all the objects below this particular class.
删除当您有要删除的对象的子类时,这可能会导致问题。请记住,构建是自上而下的,删除是自下而上的。因此,如果删除位于层次结构的中间,您基本上会丢失此特定类下的所有对象。
delete this comes very handy when you are implementing a reference counted object, an example of which is the COM classes.
delete 这在您实现引用计数对象时非常方便,其中一个示例是 COM 类。
回答by Steve Rowe
Yes. It should be perfectly fine. "This" is just a pointer. Any pointer will do for delete. The information on how to delete an object is contained in the heap records. This is how IUnknown::Release() is usually implemented in COM objects.
是的。应该没问题。“这”只是一个指针。任何指针都可以用于删除。有关如何删除对象的信息包含在堆记录中。这就是 IUnknown::Release() 通常在 COM 对象中实现的方式。
回答by hacken
回答by Martin York
Legal Yes
Safe No
合法 是
安全 否
回答by Rishabh Agrawal
If you are inheriting from a base class and gave delete this in the base class function, using derived class pointer will cause a crash. E.g:
如果您是从基类继承并在基类函数中给了 delete this,则使用派生类指针会导致崩溃。例如:
class Base
{
virtual void Release()
{
delete this;
}
}
class Derived : public Base
{
void Foo()
{
...
}
}
main()
{
Base *ptrDerived = new Derived();
ptrDerived->release();
ptrDerived->Foo() //Crash
}