1. Vấn đề nó giải quyết
Destructor chạy khi lifetime của đối tượng kết thúc, tạo nên RAII: lấy tài nguyên trong đối tượng và tự trả khi rời scope. Nó làm ràng buộc quan trọng hiện rõ thay vì bắt người đọc đoán. Bài chỉ giữ phần cốt lõi C++11 vừa đủ cho một ngày tập trung.
2. Kiến thức cần có
Kiến thức Ngày 12, cùng biến, hàm và cách đọc output đã học trước đó.
3. Ý tưởng cốt lõi
Mental model: Destructor chạy khi lifetime của đối tượng kết thúc, tạo nên RAII: lấy tài nguyên trong đối tượng và tự trả khi rời scope. Hãy xác định giá trị hoặc trạng thái liên quan, ai sở hữu nó và quy tắc tác động lúc compile hay lúc chạy.
4. Cú pháp tối thiểu
Guard g(resource); // g releases resource in ~Guard()5. Cách nó hoạt động
Ví dụ tạo dữ liệu nhỏ, cố định và không cần nhập bàn phím.
C++11 hoặc contract thư viện chuẩn áp dụng quy tắc hôm nay.
Chương trình in kết quả quan trọng để đối chiếu với mã nguồn.
6. Lỗi thường gặp
Chỉ dọn thủ công ở đường chạy bình thường sẽ rò tài nguyên khi return sớm hoặc exception bỏ qua đoạn dọn.
7. Khi nào nên dùng
Nên dùng khi tài nguyên có một chủ sở hữu rõ ràng và phải được trả ở mọi đường thoát.
Tránh dùng khi nó che ownership, lifetime, kiểu, thứ tự hoặc chi phí.
8. Ví dụ đơn giản
Guard đánh dấu tài nguyên Boolean đã được lấy trong constructor và tự xóa dấu khi block bên trong kết thúc. File .cpp dùng dữ liệu cố định và không thêm abstraction ngoài chủ đề.
Mã mẫu hoàn chỉnh
Tệp mã nguồn
cpp11/13_destructors_raii/main.cpp
#include <iostream>
class Guard {
public:
explicit Guard(bool& resource) : resource_(resource) {
resource_ = true;
std::cout << "acquired\n";
}
~Guard() {
resource_ = false;
std::cout << "released\n";
}
private:
bool& resource_;
};
int main() {
bool in_use = false;
{
Guard guard(in_use);
std::cout << "inside=" << in_use << '\n';
} // guard releases automatically
std::cout << "outside=" << in_use << '\n';
}
9. Điều cần nhớ
Tính năng nằm trong phạm vi C++11 của lộ trình này.
Hiểu hệ quả về lifetime, ownership, kiểu và thứ tự trước khi dùng.
Compile với cảnh báo và ưu tiên cách viết nhỏ nhất làm quy tắc hiện rõ.
10. Câu hỏi tự kiểm tra
Dễ — RAII dùng constructor và destructor để quản lý tài nguyên thế nào? Với biến cục bộ
Guard g(resource), hàm nào chịu trách nhiệm trả tài nguyên khi rời khối?Trung bình — Đọc ví dụ nhỏ ở trên. Chương trình sẽ in giá trị hoặc trạng thái nào, và quy tắc nào tạo ra kết quả đó?
Khó — Tìm và giải thích lỗi tinh tế trong tình huống sau: Chỉ dọn thủ công ở đường chạy bình thường sẽ rò tài nguyên khi return sớm hoặc exception bỏ qua đoạn dọn. Cách sửa nhỏ nhất nhưng an toàn trong C++11 là gì?