应该“删除这个”从成员方法中调用?

发布于 2024-08-13 13:45:07 字数 215 浏览 2 评论 0原文

我刚刚读了这篇文章 并希望得到大家的建议:

问:应该从成员方法中调用 delete this; 吗?

I was just reading this article and wanted SO folks advice:

Q: Should delete this; be called from within a member method?

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

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

发布评论

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

评论(12

暗喜 2024-08-20 13:45:07

通常这是一个坏主意,但有时很有用。

只要删除后不使用任何成员变量,并且只要调用此方法的客户端了解它可能会删除该对象,那么它就是完全安全的。

一个很好的例子说明这何时有用,如果你的类使用引用计数:

void Ref() {
  m_References++;
}

void Deref() {
  m_References--;
  if (m_References == 0) {
    delete this;
  }
}

Normally this is a bad idea, but it's occasionally useful.

It's perfectly safe as long as you don't use any member variables after you delete, and as long as clients calling this method understand it may delete the object.

A good example of when this is useful is if your class employs reference counting:

void Ref() {
  m_References++;
}

void Deref() {
  m_References--;
  if (m_References == 0) {
    delete this;
  }
}
颜漓半夏 2024-08-20 13:45:07

我认为这里确实有两个问题

可以从成员方法中有效调用删除它吗?

是的。只要您非常小心使用,这是合法的。

应该在成员方法中使用删除它吗?

在非常特殊的情况下这是必要的。例如,某些类型的智能指针使用delete this模式来终止指针。示例:CComPtr<> 样式。

不过,除了智能指针之外,应该避免使用它,除非您有充分的理由这样做。即便如此,我也会仔细地重新考虑我的场景,看看是否有解决办法。

I think there are really 2 questions here

Can delete this be validly called from a member method?

Yes. This is legal as long as you are very careful with the usage.

Should delete this be used within a member method?

In very specific cases this is necessary. Certain types of smart pointers for instance use the delete this pattern to kill the pointer. Examples: CComPtr<> style.

Other than smart pointers though, it should be avoided unless you have a very good reason for doing this. Even then, I would carefully reconsider my scenario and see if there was a way around it.

等数载,海棠开 2024-08-20 13:45:07

是的,您可以,这里很好地解释了何时以及为何

Yes you can and here's a good explanation of when and why

千笙结 2024-08-20 13:45:07

是的,有一些情况是常见的。

引用计数:

void release() 
{
  cnt--;
  if (cnt == 0) 
    delete this;
}

GUI 编程。在某些框架中,当用户关闭窗口时,窗口通常会删除自身。

Yes, there are a few cases where it is common.

Reference counting:

void release() 
{
  cnt--;
  if (cnt == 0) 
    delete this;
}

GUI programming. In some frameworks, when a user closes a window it is common for the window to delete itself.

奈何桥上唱咆哮 2024-08-20 13:45:07

为反对票做好准备。

应该:不。
技术上可以:可以
这是个好主意:绝对不是。
在什么情况下有用:当然。如果你是 C++,foo 就非常强大。但大多数人都没有那么好。因此,只有当您有一个与您一起工作的团队能够进行良好的代码审查时,才可以这样做。

原因
对象无法知道它已被动态分配(因此需要删除)还是普通对象(因此不得删除),因此它如何决定是否应该删除它。因此,如果一个对象正在删除自身,那么在我看来,设计就存在严重错误。

如果您有一个需要管理的对象,那么您应该编写一个单独的对象来进行管理(因此是智能指针)。让对象做它擅长的事情,然后将对象的管理分离到另一个对象中。

Getting ready for the down votes.

Should it: No.
Can it Technically: Yes
Is it a good idea: Absolutely not.
Are there situation it is useful: Of course. If you are C++ foo is exceedingly strong. But most people are not that good. So only do this if you have a team of people working with you able to do decent code review.

Why:
There is no way for an object to know that it has been dynamically allocated (and thus needs deleting) or is a normal object (and thus must not be deleted) and thus how can it decidide weather it should be deleted. Thus if an object is deleting itself then in my opinion there is somthing terribly wrong with the design.

If you have an object that needs managing then you should write a seprate object to do the management (hence smart pointers). Let the object do what it is good at, then seporate the management of the object into another object.

惯饮孤独 2024-08-20 13:45:07

这样做并非没有充分的理由。

问题是,当您在成员函数中调用 delete this 时,您会产生令人讨厌的副作用 - 调用者仍然拥有对您的实例的引用,但现在该引用完全无效。

这可能不是预期的行为,因此很容易导致严重的错误。

话虽如此,有时这是合适的(我见过一些内存管理方案,使用某些库,您可以在类中显式创建删除自身的方法 - 主要是为了语言互操作性)。但总的来说,我认为这是不好的做法。

Not without a very good reason to do so.

The problem is that when you call delete this in a member function, you're creating a nasty side effect - the caller still has a reference to your instance that is now completely invalid.

This is probably not an expected behavior, so it could easily lead to nasty bugs.

That being said, there are times when this is appropriate (I've seen some memory management schemes, with certain libraries, where you explicitly create methods in the classes that delete themselves - primarily for language interoperability). In general, I think it's bad practice, though.

影子的影子 2024-08-20 13:45:07

一些线程库在线程终止时实现自动销毁时使用它。

void Thread::threadFunc()
{
    doRun();

    if(this->destroyOnExit == true)
        delete this;
}

Some threading libraries use it when implementing an auto destroy on thread termination.

void Thread::threadFunc()
{
    doRun();

    if(this->destroyOnExit == true)
        delete this;
}
少年亿悲伤 2024-08-20 13:45:07

这在 MFC 时代经常被使用。 IIRC 窗口收到的最后一条消息是 WM_NCDESTROY,此时您可以调用 delete this,当然假设您是某种形式的虐待狂(尽管 MFC 本身有时会这样做)我认为。)

This was often used in the MFC days. IIRC the last message a window receives is WM_NCDESTROY, at which point you could call delete this, assuming you were some form of sadist of course (although MFC itself did this at times I think.)

菩提树下叶撕阳。 2024-08-20 13:45:07

是的。就像所有答案所说的那样,如果您 100% 确定在调用 delete this 后不会使用该类的数据。

例如,在一个项目中:

void Test()
MyClass * Someclass = new MyClass;
SomeClass->DoYourThing();
SomeClass->KillYourself();
return;

void MyClass::DoYourThing() { return; }
void MyClass::KillYourself() {delete this;}

非常简单的解释,该项目使用 delete this; 作为该类型对象的内存管理的一部分;它们的构造函数将它们添加到正在使用的该类型的类的私有列表中,并在它们被销毁时将其自身从该列表中删除,然后将其自身删除(这不在析构函数中)。当程序到达其端点时,该类中任何未删除自身的对象都会从静态成员函数 CleanYourselves() 中调用其 KillYourself() 等效项

Yes. Like all the answers say, if you're 100% sure that the class's data will not be used after the delete this is called.

For example, in one project:

void Test()
MyClass * Someclass = new MyClass;
SomeClass->DoYourThing();
SomeClass->KillYourself();
return;

void MyClass::DoYourThing() { return; }
void MyClass::KillYourself() {delete this;}

Very simplistic explanation, the project used delete this; as part of the memory management for objects of that type; their constructor added them to a private list of classes of that type in use, and removed themselves from that list when they were destroyed and then deleted themselves (this was not in a destructor). Any objects of that class that hadn't deleted themselves when the program reached its endpoint then all had their KillYourself() equivalent called from a static member function CleanYourselves()

南薇 2024-08-20 13:45:07

虽然与该线程没有直接关系,但我想澄清这一点。
有人问我一个针对特定情况的问题:

int* a = new int ;
int* b = a ;
delete a;

现在下一个语句安全吗?

cout<<*b ;

我的答案:
删除 a 后,a 指向的位置已被标记为删除,并且在任何时间点都可以将其分配给其他对象。因此,使用 b 访问该值并不安全,因为它在分配给其他对象后可能会被修改。

注意:请不要投反对票,这只是一个澄清

Although not directly related to this thread i wanted to clarify this.
I was asked a question that given a situation:

int* a = new int ;
int* b = a ;
delete a;

Now is the next statement safe?

cout<<*b ;

My answer:
After delete a, the location pointed to by a has been marked for deletion and at any point of time it can be assigned to some other object. Hence accessing the value using b is not safe as it may get modified after being allocated to some other object.

Note: No downvoting please, this is just a clarification

简单 2024-08-20 13:45:07

你可以做到这一点,只要它是成员函数中的最后一个元素,并且在返回后你会忘记该对象曾经存在过......但是,是的,就像那篇文章所问的......你为什么要这样做?我不知道标准说什么,但它确实给了我一种有趣的感觉:P

我想这有点像你是否应该使用 GOTO 语句,我个人有时会使用 GOTO 来清理 C 中的资源,尤其是在特殊的条件。

我想知道共享状态的含义是什么(我知道的模糊陈述):P

You can do it, provided its the last element in a member function, and that after return you forget that object ever existed.... but yeah, like that article asks ... Why would you want to do this ? I don't know what the standard says, but it does give me a funny feeling :P

I guess this is a bit like should you ever use a GOTO statement, and I personally use GOTO to clean up resources in C sometimes, especially under exceptional conditions.

I wonder what the shared state implications are (fuzzy statement I know):P

苏璃陌 2024-08-20 13:45:07
  1. 不能从非成员函数调用 delete this :)
  2. 在您了解其后果之前,这样做是一个坏主意。
  1. delete this can not be called from a non member function :)
  2. It is a bad idea to do until you understand it's consequences.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文