C++ 中的“delete this”?


delete 是一个用于释放变量存储空间的操作符。

this 指针是一种可以访问的指针,但只能在非静态成员函数内部访问,它指向调用成员函数的对象的地址。

this 指针保存当前对象的地址,简单来说,你可以说 this 指针指向类的当前对象。

每当我们通过其对象调用成员函数时,编译器都会秘密地将调用该对象的地址作为第一个参数传递给成员函数作为 this 指针。

通常,不应将 delete 操作符用于 this 指针。假设,如果使用,则必须考虑以下几点。

理想情况下,不应将 delete 操作符用于 this 指针。但是,如果使用,则必须考虑以下几点。

  • delete 操作符仅适用于使用 new 操作符分配的对象(请参阅此帖子)。如果对象是使用 new 创建的,那么我们可以执行 delete this,否则,行为未定义。

filter_none
edit
play_arrow
brightness_4
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();
   getchar();
   return 0;
}
  • 一旦执行了 delete this,则在删除后不应访问已删除对象的任何成员。

filter_none
edit
play_arrow
brightness_4
#include<iostream>
using namespace std;
class A {
   int x;
   public:
   A() { x = 0;}
   void fun() {
      delete this;
      /* Invalid: Undefined Behavior */
      cout<<x;
   }
};

最好的办法是根本不做 delete this。

在成员函数内部删除 this 指针是错误的,我们永远不应该这样做。但是,如果我们这样做,可能会发生以下情况,

  • 如果调用此成员函数的对象是在栈上创建的,那么删除 this 指针要么使应用程序崩溃,要么会导致未定义的行为。

  • 如果调用此成员函数的对象是使用 new 操作符在堆上创建的,那么删除 this 指针将销毁该对象。它不会在那个特定时间使应用程序崩溃,但在之后,如果某些成员函数尝试通过此对象访问成员变量,那么应用程序将崩溃。

示例

#include <iostream>
class Dummy {
   int m_value;
   public:
   Dummy(int val) :
   m_value(val)
   {}
   void destroy();
   void displayValue();
   void displayText();
};
void Dummy::destroy() {
   delete this;
}
void Dummy::displayValue() {
   std::cout << this->m_value << std::endl;
}
void Dummy::displayText() {
   std::cout << "Not accessing any member function" << std::endl;
}
int main() {
   Dummy * dummyPtr = new Dummy(5);
   dummyPtr->destroy();
   dummyPtr->displayText();
   return 0;
}

一旦我们在 destroy() 成员函数中删除了 this 指针,之后调用 displayText() 是安全的,因为它没有访问任何成员函数。但是调用 displayValue() 将使应用程序崩溃,因为它通过悬空指针(即已删除的 this 指针)访问成员变量。

更新于: 2019年8月20日

2K+ 浏览量

开启你的 职业生涯

通过完成课程获得认证

开始学习
广告