“删除这个”安全吗?

发布于 2024-07-13 20:31:19 字数 151 浏览 6 评论 0原文

在我最初的基本测试中,这样做是完全安全的。 然而,令我震惊的是,稍后在删除 this 的函数中尝试操作 this 可能会导致运行时错误。 这是真的吗?删除此内容通常安全吗? 还是只有某些情况下它是安全的?

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 deletes 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

远昼 2024-07-20 20:31:19

delete this 是合法的,并且执行您所期望的操作:它调用类的析构函数并释放底层内存。 delete this 返回后,您的 this 指针值不会发生变化,因此它现在是一个悬空指针,不应该 > 被取消引用。 这包括使用类的成员变量进行隐式取消引用。

在引用计数类中通常会发现,当引用计数递减到 0 时,DecrementRefCount()/Release()/whatever 成员函数会调用 删除这个

由于多种原因,删除此内容通常被认为是非常糟糕的形式。 删除此后很容易意外访问成员变量。 调用者代码可能没有意识到您的对象已自毁。

另外,删除这个是一种“代码味道”,您的代码可能没有对象所有权的对称策略(谁分配和谁删除)。 对象无法使用new分配自身,因此调用delete this意味着类A正在分配一个对象,但类B稍后会释放它[self] .

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 not change, so it is now a dangling pointer that should not be dereferenced. That includes implicit dereferencing using the class's member variables.

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.

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.

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].

不弃不离 2024-07-20 20:31:19

删除“this”是安全的,只要它本质上是方法中的最后一个操作。 事实上,几个专业级 API 都这样做(请参阅 ATL 的 CComObject 实现示例)。

唯一的危险是在调用“删除此”后尝试访问任何其他成员数据。 这当然是不安全的。

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).

The only danger is attempting to access any other member data after calling "delete this". This is certainly unsafe.

清旖 2024-07-20 20:31:19

正如其他人已经提到的那样,删除它是完全合法的。 由于还有一个尚未提及的原因,这是有风险的 - 您假设该对象已在堆上分配。 这可能很难保证,尽管在引用计数实现的情况下通常不是问题。

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.

一刻暧昧 2024-07-20 20:31:19

但不要在析构函数中这样做!

but dont do it in the destructor !

千寻… 2024-07-20 20:31:19

正如其他人所说,删除这是一个有效的习惯用法,但为了安全起见,您必须确保该对象永远不会在堆栈上实例化。

实现此目的的一种方法是将构造函数和析构函数设为私有,并通过类工厂函数强制创建对象,该函数在堆上创建对象并返回指向该对象的指针。 类工厂可以是静态成员函数或友元函数。 然后可以通过执行“删除此”的对象上的 Delete() 方法来完成清理。 COM 对象基本上以这种方式工作,除了它们是引用计数的,当引用计数递减到零时发生“删除此”。

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.

趴在窗边数星星i 2024-07-20 20:31:19

是的。 应该是完全没问题的。 “这”只是一个指针。 任何指针都可以用于删除。 有关如何删除对象的信息包含在堆记录中。 这就是 IUnknown::Release() 通常在 COM 对象中实现的方式。

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.

蓝海似她心 2024-07-20 20:31:19

当您有要删除的对象的子类时,这可能会导致问题。 请记住,构建是从上到下开始的,删除是从下到上开始的。 因此,如果删除位于层次结构中间的对象,您基本上会丢失该特定类下面的所有对象。

当您实现引用计数对象时(COM 类就是一个例子),delete 这会非常方便。

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.

幸福不弃 2024-07-20 20:31:19

阅读进行类似的讨论。 您的理解是正确的,因为它确实有效,是必需的,并且可能很危险,因为您之后无法访问它。

Read for a similiar discussion. Your understanding is right in that it does work, is needed, and can be dangerous since you can't access this afterwards.

夏夜暖风 2024-07-20 20:31:19

合法 是
安全号

Legal Yes
Safe No

苏大泽ㄣ 2024-07-20 20:31:19

如果您从基类继承并在基类函数中给出了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

}

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:

class Base
{

    virtual void Release()
    {
        delete this;
    }

}

class Derived : public Base
{

    void Foo()
    {
        ...
    }

}

main()
{

    Base *ptrDerived = new Derived();
    ptrDerived->release();
    ptrDerived->Foo() //Crash

}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文