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() จะทำให้แอปพลิเคชั่นหยุดทำงาน เพราะมันกำลังเข้าถึงตัวแปรของสมาชิกผ่านตัวชี้ที่ห้อยอยู่นั่นคือลบตัวชี้นี้ออก