Đúng.
"Tác hại" duy nhất có thể làm là đưa sự kém hiệu quả (một hoạt động lưu trữ không cần thiết) vào chương trình của bạn - nhưng chi phí này sẽ không đáng kể liên quan đến chi phí phân bổ và giải phóng khối bộ nhớ trong hầu hết các trường hợp.
Nếu bạn không làm điều đó, một ngày nào đó bạn sẽ gặp phải một số lỗi khó chịu.
Tôi luôn sử dụng macro để xóa:
#define SAFEDELETE(ptr) { delete(ptr); ptr = NULL; }
(và tương tự cho một mảng, free (), giải phóng tay cầm)
Bạn cũng có thể viết các phương thức "tự xóa" lấy tham chiếu đến con trỏ của mã gọi, để chúng buộc con trỏ của mã gọi đến NULL. Ví dụ: để xóa một cây con của nhiều đối tượng:
static void TreeItem::DeleteSubtree(TreeItem *&rootObject)
{
if (rootObject == NULL)
return;
rootObject->UnlinkFromParent();
for (int i = 0; i < numChildren)
DeleteSubtree(rootObject->child[i]);
delete rootObject;
rootObject = NULL;
}
biên tập
Vâng, các kỹ thuật này vi phạm một số quy tắc về việc sử dụng macro (và vâng, ngày nay bạn có thể đạt được kết quả tương tự với các mẫu) - nhưng bằng cách sử dụng trong nhiều năm, tôi chưa bao giờ truy cập vào bộ nhớ chết - một trong những điều khó khăn và khó khăn nhất và tốn nhiều thời gian nhất để gỡ lỗi các vấn đề bạn có thể gặp phải. Trong thực tế trong nhiều năm, họ đã loại bỏ một cách hiệu quả một lớp lỗi từ mọi đội tôi đã giới thiệu cho họ.
Ngoài ra còn có nhiều cách bạn có thể thực hiện như trên - Tôi chỉ cố gắng minh họa ý tưởng buộc mọi người phải NULL một con trỏ nếu họ xóa một đối tượng, thay vì cung cấp một phương tiện để họ giải phóng bộ nhớ không NULL con trỏ của người gọi .
Tất nhiên, ví dụ trên chỉ là một bước tiến tới một con trỏ tự động. Điều mà tôi không đề xuất vì OP đặc biệt hỏi về trường hợp không sử dụng con trỏ tự động.
delete
một con trỏ null, đó là một lý do khiến con trỏ không có thể tốt.