delete เป็นตัวดำเนินการที่ใช้ปล่อยพื้นที่จัดเก็บของตัวแปร
this pointer เป็นตัวชี้ที่เข้าถึงได้เฉพาะภายใน non-static member function และชี้ไปยังที่อยู่ของออบเจ็กต์ที่เรียก member function นั้น
this pointer เก็บที่อยู่ของออบเจ็กต์ปัจจุบัน อย่างง่ายคือ this pointer ชี้ไปยังออบเจ็กต์ปัจจุบันของคลาส
ทุกครั้งที่เราเรียก member function ผ่านออบเจ็กต์ คอมไพเลอร์จะส่งที่อยู่ของออบเจ็กต์ที่เรียกเป็นพารามิเตอร์แรกใน member function ผ่าน this pointer โดยลับๆ
โดยหลักทั่วไป delete operator ไม่ควรใช้กับ this pointer สมมติถ้าใช้ จะต้องพิจารณาจุดต่อไปนี้
ในทางที่เป็นจริง delete operator ไม่ควรใช้กับ this pointer อย่างไรก็ตาม หากใช้ จะต้องพิจารณาดังนี้:
delete operator ทำงานได้เฉพาะกับออบเจ็กต์ที่จัดสรรด้วย operator new (ดูโพสต์นี้) หากออบเจ็กต์ถูกสร้างด้วย new เราสามารถทำ delete this ได้ มิฉะนั้นพฤติกรรมจะไม่ได้รับการกำหนด (undefined behavior)
class A {
public:
void fun() {
delete this;
}
};
int main() {
/* ต่อไปนี้ถูกต้อง */
A *ptr = new A;
ptr->fun();
ptr = NULL; // ทำให้ ptr เป็น NULL เพื่อให้แน่ใจว่าไม่เข้าถึงผ่าน ptr
/* และต่อไปนี้ไม่ถูกต้อง: Undefined Behavior */
A a;
a.fun();
getchar();
return 0;
}
หลังจาก delete this แล้ว สมาชิกของออบเจ็กต์ที่ถูกลบไม่ควรถูกเข้าถึงหลังการลบ
#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 pointer ภายใน member function เป็นสิ่งผิด เราไม่ควรทำ แต่ถ้าทำ สิ่งต่อไปนี้อาจเกิดขึ้น:
ถ้าออบเจ็กต์ที่เรียก member function นั้นถูกสร้างบน stack การลบ this pointer จะทำให้แอปพลิเคชัน crash หรือพฤติกรรมไม่ได้รับการกำหนด
ถ้าออบเจ็กต์ถูกสร้างบน heap ด้วย new operator การลบ this pointer จะทำลายออบเจ็กต์ จะไม่ crash ทันที แต่หลังจากนั้นถ้า member function พยายามเข้าถึงตัวแปรสมาชิกผ่านออบเจ็กต์นี้ แอปพลิเคชันจะ crash
ตัวอย่าง
#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;
}
เมื่อเราลบ this pointer ใน destroy() member function แล้ว การเรียก displayText() ปลอดภัยเพราะไม่เข้าถึงสมาชิกใดๆ แต่การเรียก displayValue() จะทำให้แอปพลิเคชัน crash เพราะเข้าถึงตัวแปรสมาชิกผ่าน dangling pointer คือ this pointer ที่ถูกลบแล้ว