Delete เป็นโอเปอเรเตอร์ที่ใช้ในการจัดสรรพื้นที่จัดเก็บของตัวแปร
ตัวชี้นี้เป็นตัวชี้ชนิดหนึ่งที่สามารถเข้าถึงได้แต่ภายในฟังก์ชันสมาชิกที่ไม่คงที่เท่านั้น และชี้ไปยังที่อยู่ของวัตถุที่เรียกใช้ฟังก์ชันสมาชิก
ตัวชี้นี้เก็บที่อยู่ของวัตถุปัจจุบัน พูดง่ายๆ ว่าตัวชี้นี้ชี้ไปที่วัตถุปัจจุบันของชั้นเรียน
เมื่อใดก็ตามที่เราเรียกใช้ฟังก์ชันสมาชิกผ่านอ็อบเจ็กต์ คอมไพเลอร์จะส่งที่อยู่ของการเรียกอ็อบเจ็กต์นั้นเป็นพารามิเตอร์แรกในฟังก์ชันสมาชิกอย่างลับๆ เป็นตัวชี้นี้
โดยทั่วไป ไม่ควรใช้ตัวดำเนินการลบสำหรับตัวชี้นี้ สมมติว่าหากใช้แล้วต้องพิจารณาประเด็นต่อไปนี้
ตามหลักการแล้ว ไม่ควรใช้ตัวดำเนินการลบสำหรับตัวชี้นี้ อย่างไรก็ตามหากใช้แล้วต้องพิจารณาประเด็นต่อไปนี้
-
ตัวดำเนินการลบใช้งานได้กับวัตถุที่จัดสรรโดยใช้ตัวดำเนินการใหม่เท่านั้น (ดูโพสต์นี้) หากวัตถุถูกสร้างขึ้นโดยใช้ new เราสามารถลบสิ่งนี้ได้ มิฉะนั้น พฤติกรรมจะไม่ถูกกำหนด
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; }
-
เมื่อลบเสร็จแล้ว ไม่ควรเข้าถึงสมาชิกของวัตถุที่ถูกลบหลังจากการลบ
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; } };
สิ่งที่ดีที่สุดคืออย่าลบสิ่งนี้เลย
การลบตัวชี้ภายในฟังก์ชันสมาชิกนั้นผิด เราไม่ควรทำเช่นนั้น แต่ถ้าเราทำสิ่งต่อไปนี้อาจเกิดขึ้นได้
-
หากวัตถุที่เรียกใช้ฟังก์ชันสมาชิกนี้ถูกสร้างขึ้นบนสแต็ก การลบตัวชี้นี้อาจทำให้แอปพลิเคชันของคุณขัดข้องหรือจะส่งผลให้เกิดการทำงานที่ไม่ได้กำหนดไว้
-
หากอ็อบเจ็กต์ที่เรียกใช้ฟังก์ชันสมาชิกนี้ถูกสร้างขึ้นบนฮีปโดยใช้ตัวดำเนินการใหม่ การลบตัวชี้นี้จะทำลายอ็อบเจ็กต์ จะไม่ทำให้แอปพลิเคชันขัดข้องในขณะนั้น แต่หลังจากนั้น หากฟังก์ชันของสมาชิกบางส่วนพยายามเข้าถึงตัวแปรสมาชิกผ่านวัตถุนี้ แอปพลิเคชันก็จะขัดข้อง
ตัวอย่าง
#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() หลังจากการเรียก displayText() จะปลอดภัยเพราะไม่ได้เข้าถึงฟังก์ชันของสมาชิก แต่การเรียก displayValue() จะทำให้แอปพลิเคชั่นหยุดทำงาน เพราะมันกำลังเข้าถึงตัวแปรของสมาชิกผ่านตัวชี้ที่ห้อยอยู่นั่นคือลบตัวชี้นี้ออก