繁体   English   中英

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

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

如果成员 function 尝试delete this; ,比如在下面的class的构造函数中?

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

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

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

这个C++ FAQ 条目很好地回答了这个问题,在这里重复:

只要你小心,object delete this .

以下是我对“小心”的定义:

  • 您必须绝对 100% 肯定地确定此 object 是通过 new 分配的(不是通过 new[],也不是通过放置 new,也不是堆栈上的本地 object,也不是全局的,也不是另一个 ZA8CFDE6331BD49EB6666F8911 的成员,而是普通的 C;新的)。
  • 您必须绝对 100% 肯定地确定您的成员 function 将是在此 object 上调用的最后一个成员 function。
  • 您必须绝对 100% 肯定您的会员 function 的 rest(删除此行之后)不会触及此 object 的任何部分(包括呼叫任何会员功能)。
  • 您必须绝对 100% 肯定地确定在删除此行之后甚至没有人触摸 this 指针本身。 换句话说,你不能检查它,将它与另一个指针进行比较,将它与 NULL 进行比较,打印它,投射它,用它做任何事情。

delete this后访问pi违反了#3

坏事。 你可以delete this; 但这通常是一个非常糟糕的主意,一旦完成,您就无法触摸任何成员变量或成员函数。

一般来说,从成员 function 内部调用delete this是明确定义的,如果有一点风险的话。

但是从构造函数调用它可能是一个非常糟糕的主意(我不知道它是否定义明确)。 为什么你会想要那样做?

您可以delete this ,但这假定该实例是使用new创建的,并且您不再访问该实例的任何成员。

在您的示例中,如果您这样做,几乎会发生相同的情况

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
}

更糟糕的事情发生了,因为当你delete this时, pi成员被统一化,导致析构函数试图删除一个悬空指针。

使用 delete this 是一种不好的做法,但是,如果使用,则必须考虑以下几点。

1) delete 运算符仅适用于使用 new 运算符分配的对象。 如果 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)一旦删除完成,删除后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