delete là toán tử giải phóng bộ nhớ của biến.
this pointer là con trỏ chỉ truy cập được trong hàm thành viên non-static, trỏ đến địa chỉ đối tượng gọi hàm thành viên đó.
this pointer giữ địa chỉ đối tượng hiện tại, đơn giản là this trỏ đến đối tượng hiện tại của lớp.
Khi gọi hàm thành viên qua đối tượng, trình biên dịch tự động truyền địa chỉ đối tượng gọi làm tham số đầu tiên là this pointer.
Thông thường, delete không nên dùng cho this pointer. Nếu dùng, phải xem xét:
delete chỉ hoạt động cho đối tượng cấp phát bằng operator new. Nếu đối tượng tạo bằng new, có thể delete this, ngược lại hành vi không xác định.
class A {
public:
void fun() { delete this; }
};
int main() {
/* Hợp lệ */
A *ptr = new A;
ptr->fun();
ptr = NULL; // tránh truy cập qua ptr
/* Không hợp lệ: Undefined Behavior */
A a;
a.fun();
return 0;
} Sau delete this, không được truy cập bất kỳ thành viên nào của đối tượng đã xóa.
#include <iostream>
using namespace std;
class A {
int x;
public:
A() { x = 0; }
void fun() {
delete this;
/* Không hợp lệ: Undefined Behavior */
cout << x;
}
}; Tốt nhất là KHÔNG BAO GIỜ dùng delete this.
Xóa this pointer trong hàm thành viên là sai, không nên làm. Nhưng nếu làm, có thể xảy ra:
- Nếu đối tượng tạo trên stack: delete this hoặc crash app hoặc undefined behavior.
- Nếu đối tượng tạo trên heap bằng new: delete this sẽ hủy đối tượng. Không crash ngay nhưng sau đó nếu hàm thành viên khác truy cập biến thành viên qua đối tượng này thì app sẽ crash.
Ví dụ
#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 << "Không truy cập thành viên" << std::endl; }
int main() {
Dummy * dummyPtr = new Dummy(5);
dummyPtr->destroy();
dummyPtr->displayText();
return 0;
} Sau khi xóa this trong destroy(), gọi displayText() an toàn vì không truy cập thành viên. Nhưng displayValue() sẽ crash vì truy cập biến qua con trỏ treo (dangling pointer = deleted this).