“删除这个”是个坏主意吗? [重复]

时间:2022-11-03 09:53:33

Possible Duplicate:
Is it safe to delete this?

可能重复:删除它是否安全?

I've been doing a little work on a class that's designed to act as a node in a linked list, and I figured I'd give the class its own deletion function as opposed to the managing class doing it. So basically it goes like this:

我一直在为一个设计用作链表中的节点的类做一些工作,我想我会给类自己的删除功能而不是管理类这样做。所以基本上它是这样的:

void Class::Delete() {
    //Some cleanup code before deleting the object
    delete this;
}

Now I've tested this and it appears to work fine, but I've had a problem in the past where objects have been in the middle of running code, been deleted, then obviously crashed the program by trying to use a no-longer-existing object.

现在我已经对它进行了测试,看起来效果很好,但是过去我遇到了一个问题,即对象一直处于运行代码的中间,被删除,然后显然是通过尝试使用不再使程序崩溃存在的对象。

Since "delete this" is right at the end of the function, it obviously exits the function and works fine, but is this sort of practice a bad idea at all? Could this ever blow up in my face if I'm not careful?

由于“删除这个”就在函数的最后,它显然退出了函数并且工作正常,但这种做法是不是一个坏主意?如果我不小心,这会不会在我脸上爆炸?

5 个解决方案

#1


21  

The FAQlite answers this quite well:

FAQlite很好地回答了这个问题:

As long as you're careful, it's OK for an object to commit suicide (delete this).

只要你小心,对象就可以自杀了(删除它)。

Here's how I define "careful":

这是我如何定义“小心”:

  1. You must be absolutely 100% positive sure that this object was allocated via new (not by new[], nor by placement new, nor a local object on the stack, nor a global, nor a member of another object; but by plain ordinary new).
  2. 你必须绝对100%肯定这个对象是通过new(不是new [],也不是通过放置new,也不是堆栈上的本地对象,也不是全局,也不是​​另一个对象的成员;但是通过普通的新)。

  3. You must be absolutely 100% positive sure that your member function will be the last member function invoked on this object.
  4. 您必须绝对100%肯定您的成员函数将是在此对象上调用的最后一个成员函数。

  5. You must be absolutely 100% positive sure that the rest of your member function (after the delete this line) doesn't touch any piece of this object (including calling any other member functions or touching any data members).
  6. 您必须绝对100%肯定您的成员函数的其余部分(在删除此行之后)不会触及此对象的任何部分(包括调用任何其他成员函数或触摸任何数据成员)。

  7. You must be absolutely 100% positive sure that no one even touches the this pointer itself after the delete this line. In other words, you must not examine it, compare it with another pointer, compare it with NULL, print it, cast it, do anything with it.
  8. 在删除此行之后,您必须绝对100%肯定没有人甚至触及此指针本身。换句话说,你不能检查它,将它与另一个指针进行比较,将它与NULL进行比较,打印,投射,用它做任何事情。

Naturally the usual caveats apply in cases where your this pointer is a pointer to a base class when you don't have a virtual destructor.

当然,当您没有虚拟析构函数时,此指针是指向基类的指针时,通常需要注意。

Basically, you need to take the same care as you do with deleteing any other pointer. However, there are more areas where things can go wrong with a member function committing suicide, compared with an explicitly-declared pointer.

基本上,您需要像删除任何其他指针一样小心。但是,与明确声明的指针相比,有更多的区域可能会出现成员函数自杀的问题。

#2


6  

Using delete this is a bad idea if one is not sure of the pitfalls & working around them.

使用删除这是一个坏主意,如果一个人不确定陷阱和解决它们。

Once you call delete this the object's destructor is going to be invoked and the dynamically allocated memory will be freed.

一旦调用delete,就会调用对象的析构函数,并释放动态分配的内存。

If the object was not allocated using new, it will be a Undefined behaviour.
If any of object's data members or virtual functions are accessed after delete this, the behaviour will be Undefined Behavior again.

如果未使用new分配对象,则它将是未定义的行为。如果删除此对象后访问了对象的任何数据成员或虚函数,则行为将再次为未定义行为。

Probably, It is best to avoid delete this given the above.

可能,最好避免删除上面给出的内容。

#3


4  

It's actually a frequent idiom, and about as safe as any delete. As with all deletes, you have to ensure that no further code tries to access the object, and you have to be sure that the object was dynamically allocated. Typically, however, the latter is not a problem, since the idiom is only relevant for objects which have a lifetime determined by the semantics of the object, and such objects are always allocated dynamically. Finding all of the pointers too the object can be an issue (whether delete this is used or not); usually, some form of the observer pattern will be used to notify all interested parties that the object will cease to exist.

它实际上是一种常用的习惯用语,与任何删除一样安全。与所有删除一样,您必须确保没有其他代码尝试访问该对象,并且您必须确保该对象是动态分配的。然而,通常,后者不是问题,因为惯用语仅与具有由对象的语义确定的寿命的对象相关,并且这些对象总是动态地分配。找到所有指针也是一个问题(是否使用删除它);通常,某种形式的观察者模式将用于通知所有相关方该对象将不复存在。

#4


2  

The idiomatic way of doing that in C++ is by putting the cleanup code in the destructor then let it be called automatically when you delete the object.

在C ++中这样做的惯用方法是将清理代码放在析构函数中,然后在删除对象时自动调用它。

Class::~Class() {
    do_cleanup();
}

void ManagingClass::deleteNode(Class* instance) {
    delete instance; //here the destructor gets called and memory gets freed
}

#5


1  

There's a simple way of doing the same thing that doesn't involve undefined behavior:

有一种简单的方法可以做同样的事情,不涉及未定义的行为:

void Class::Delete() {
    //Some cleanup code before deleting the object
    std::auto_ptr delete_me(this);
}

#1


21  

The FAQlite answers this quite well:

FAQlite很好地回答了这个问题:

As long as you're careful, it's OK for an object to commit suicide (delete this).

只要你小心,对象就可以自杀了(删除它)。

Here's how I define "careful":

这是我如何定义“小心”:

  1. You must be absolutely 100% positive sure that this object was allocated via new (not by new[], nor by placement new, nor a local object on the stack, nor a global, nor a member of another object; but by plain ordinary new).
  2. 你必须绝对100%肯定这个对象是通过new(不是new [],也不是通过放置new,也不是堆栈上的本地对象,也不是全局,也不是​​另一个对象的成员;但是通过普通的新)。

  3. You must be absolutely 100% positive sure that your member function will be the last member function invoked on this object.
  4. 您必须绝对100%肯定您的成员函数将是在此对象上调用的最后一个成员函数。

  5. You must be absolutely 100% positive sure that the rest of your member function (after the delete this line) doesn't touch any piece of this object (including calling any other member functions or touching any data members).
  6. 您必须绝对100%肯定您的成员函数的其余部分(在删除此行之后)不会触及此对象的任何部分(包括调用任何其他成员函数或触摸任何数据成员)。

  7. You must be absolutely 100% positive sure that no one even touches the this pointer itself after the delete this line. In other words, you must not examine it, compare it with another pointer, compare it with NULL, print it, cast it, do anything with it.
  8. 在删除此行之后,您必须绝对100%肯定没有人甚至触及此指针本身。换句话说,你不能检查它,将它与另一个指针进行比较,将它与NULL进行比较,打印,投射,用它做任何事情。

Naturally the usual caveats apply in cases where your this pointer is a pointer to a base class when you don't have a virtual destructor.

当然,当您没有虚拟析构函数时,此指针是指向基类的指针时,通常需要注意。

Basically, you need to take the same care as you do with deleteing any other pointer. However, there are more areas where things can go wrong with a member function committing suicide, compared with an explicitly-declared pointer.

基本上,您需要像删除任何其他指针一样小心。但是,与明确声明的指针相比,有更多的区域可能会出现成员函数自杀的问题。

#2


6  

Using delete this is a bad idea if one is not sure of the pitfalls & working around them.

使用删除这是一个坏主意,如果一个人不确定陷阱和解决它们。

Once you call delete this the object's destructor is going to be invoked and the dynamically allocated memory will be freed.

一旦调用delete,就会调用对象的析构函数,并释放动态分配的内存。

If the object was not allocated using new, it will be a Undefined behaviour.
If any of object's data members or virtual functions are accessed after delete this, the behaviour will be Undefined Behavior again.

如果未使用new分配对象,则它将是未定义的行为。如果删除此对象后访问了对象的任何数据成员或虚函数,则行为将再次为未定义行为。

Probably, It is best to avoid delete this given the above.

可能,最好避免删除上面给出的内容。

#3


4  

It's actually a frequent idiom, and about as safe as any delete. As with all deletes, you have to ensure that no further code tries to access the object, and you have to be sure that the object was dynamically allocated. Typically, however, the latter is not a problem, since the idiom is only relevant for objects which have a lifetime determined by the semantics of the object, and such objects are always allocated dynamically. Finding all of the pointers too the object can be an issue (whether delete this is used or not); usually, some form of the observer pattern will be used to notify all interested parties that the object will cease to exist.

它实际上是一种常用的习惯用语,与任何删除一样安全。与所有删除一样,您必须确保没有其他代码尝试访问该对象,并且您必须确保该对象是动态分配的。然而,通常,后者不是问题,因为惯用语仅与具有由对象的语义确定的寿命的对象相关,并且这些对象总是动态地分配。找到所有指针也是一个问题(是否使用删除它);通常,某种形式的观察者模式将用于通知所有相关方该对象将不复存在。

#4


2  

The idiomatic way of doing that in C++ is by putting the cleanup code in the destructor then let it be called automatically when you delete the object.

在C ++中这样做的惯用方法是将清理代码放在析构函数中,然后在删除对象时自动调用它。

Class::~Class() {
    do_cleanup();
}

void ManagingClass::deleteNode(Class* instance) {
    delete instance; //here the destructor gets called and memory gets freed
}

#5


1  

There's a simple way of doing the same thing that doesn't involve undefined behavior:

有一种简单的方法可以做同样的事情,不涉及未定义的行为:

void Class::Delete() {
    //Some cleanup code before deleting the object
    std::auto_ptr delete_me(this);
}