简体   繁体   English

如果你“删除这个”会发生什么; 在成员 function 中?

[英]what will happen if you do “delete this;” in a member function?

What will exactly happen if a member function try to do delete this;如果成员 function 尝试delete this; , like in the constructor of the following class? ,比如在下面的class的构造函数中?

class A
{
public:
    A(int);
    ~A();
    int *pi;
}

A::A(int i)
{
    delete this;
    pi = new int(i);
}

A::~A()
{
    delete pi;
}

This C++ FAQ entry answers this quite nicely, repeating here:这个C++ FAQ 条目很好地回答了这个问题,在这里重复:

As long as you're careful, it's OK for an object to delete this .只要你小心,object delete this .

Here's how I define "careful":以下是我对“小心”的定义:

  • You must be absolutely 100% positively 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).您必须绝对 100% 肯定地确定此 object 是通过 new 分配的(不是通过 new[],也不是通过放置 new,也不是堆栈上的本地 object,也不是全局的,也不是另一个 ZA8CFDE6331BD49EB6666F8911 的成员,而是普通的 C;新的)。
  • You must be absolutely 100% positively sure that your member function will be the last member function invoked on this object.您必须绝对 100% 肯定地确定您的成员 function 将是在此 object 上调用的最后一个成员 function。
  • You must be absolutely 100% positively 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).您必须绝对 100% 肯定您的会员 function 的 rest(删除此行之后)不会触及此 object 的任何部分(包括呼叫任何会员功能)。
  • You must be absolutely 100% positively sure that no one even touches the this pointer itself after the delete this line.您必须绝对 100% 肯定地确定在删除此行之后甚至没有人触摸 this 指针本身。 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.换句话说,你不能检查它,将它与另一个指针进行比较,将它与 NULL 进行比较,打印它,投射它,用它做任何事情。

You are violating the #3 by accessing pi after delete this delete this后访问pi违反了#3

Bad things.坏事。 You can delete this;你可以delete this; but it's generally speaking an extremely bad idea, and once it's done, you cannot touch any member variables or member functions.但这通常是一个非常糟糕的主意,一旦完成,您就无法触摸任何成员变量或成员函数。

In general, invoking delete this from inside a member function is well-defined, if a little risky.一般来说,从成员 function 内部调用delete this是明确定义的,如果有一点风险的话。

But it's probably a very bad idea to invoke it from the constructor (I don't know if it's well-defined).但是从构造函数调用它可能是一个非常糟糕的主意(我不知道它是否定义明确)。 Why would you ever want to do that?为什么你会想要那样做?

You can delete this , but this assumes that the instance was created with new and that you don't access any members of the instance any more.您可以delete this ,但这假定该实例是使用new创建的,并且您不再访问该实例的任何成员。

In your example, pretty much the same would happen if you did在您的示例中,如果您这样做,几乎会发生相同的情况

class A
{
public:
    A(int);
    int *pi;
};

A::A(int i)
{
    pi = new int(i);
}

int main()
{
   A* p = new A(10);
   delete p;
   p->pi = new int; //bad stuff

//or
   A a(20);
   delete &a;  //bad stuff
   a.pi = new int; //more bad stuff
}

And even more bad stuff happens because when you delete this , the pi member is unitialized, leading to destructor attempting to delete a dangling pointer.更糟糕的事情发生了,因为当你delete this时, pi成员被统一化,导致析构函数试图删除一个悬空指针。

It is a bad practice to use delete this, However, if used, then following points must be considered.使用 delete this 是一种不好的做法,但是,如果使用,则必须考虑以下几点。

1) delete operator works only for objects allocated using new operator. 1) delete 运算符仅适用于使用 new 运算符分配的对象。 If the object is created using new, then we can do delete this, otherwise behavior is undefined.如果 object 是使用 new 创建的,那么我们可以删除它,否则行为未定义。

  class A {
   public:
    void fun(){
     delete this;
   }
  };

 int main(){
 /* Following is Valid */
   A *ptr = new A;
   ptr->fun();
    ptr = NULL // make ptr NULL to make sure that things are not accessed using ptr. 


   /* And following is Invalid: Undefined Behavior */
    A a;
    a.fun();

 return 0;
}

2) Once delete this is done, any member of the deleted object should not be accessed after deletion. 2)一旦删除完成,删除后object的任何成员都不应访问。

 class A {
   int x;
  public:
    A() { x = 0;}
     void fun() {
      delete this;

    /* Invalid: Undefined Behavior */
    cout<<x;
  }
 };

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM