如果你做“删除这个”会发生什么?在会员功能?

时间:2011-08-12 11:43:25

标签: c++

如果成员函数尝试执行delete this;,会发生什么情况,就像在以下类的构造函数中一样?

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

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

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

5 个答案:

答案 0 :(得分:38)

This C ++常见问题条目很好地解答了这一点,在此重复:

只要您小心,对象delete this即可。

以下是我如何定义“小心”:

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

您在pi

之后访问delete this,违反了#3

答案 1 :(得分:3)

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

答案 2 :(得分:1)

一般来说,如果风险很小,从成员函数内部调用delete this是明确定义的。

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

答案 3 :(得分:0)

您可以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成员被统一化,导致析构函数试图删除悬空指针。

答案 4 :(得分:-1)

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

1)删除运算符仅适用于使用new运算符分配的对象。如果使用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)删除完成后,删除后不应访问已删除对象的任何成员。

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

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