Bài học theo mô-đun (1/2)
std::unique_ptr và std::shared_ptr
Trong C++ cổ điển, việc quản lý bộ nhớ thủ công bằng toán tử new và delete là nguồn lỗi phổ biến như rò rỉ bộ nhớ (tài nguyên không bao giờ được giải phóng) hoặc con trỏ lơ lửng (con trỏ trỏ tới bộ nhớ đã bị giải phóng).
C++ hiện đại giới thiệu Con trỏ thông minh, được xác định trong tiêu đề <memory>. Chúng tự động quản lý vòng đời của bộ nhớ được phân bổ heap bằng cách sử dụng RAII (Khởi tạo thu thập tài nguyên), giải phóng tài nguyên khi con trỏ thông minh vượt quá phạm vi.
std::unique_ptr
std::unique_ptr triển khai khái niệm quyền sở hữu độc quyền tài nguyên. Không thể sao chép nó, chỉ di chuyển (thông qua std::move).
#include <memory>
// Recommended creation using std::make_unique (C++14)
std::unique_ptr<int> p1 = std::make_unique<int>(42);
// Accessing the resource like a normal pointer
std::cout << *p1 << std::endl;
// std::unique_ptr<int> p2 = p1; // COMPILER ERROR: copy not allowed!
std::unique_ptr<int> p2 = std::move(p1); // Allowed: p1 transfers ownership to p2std::shared_ptr
std::shared_ptr triển khai khái niệm quyền sở hữu chung. Nhiều con trỏ thông minh có thể trỏ đến cùng một tài nguyên. Lớp duy trì nội bộ số lượng tham chiếu: bộ nhớ chỉ được giải phóng khi shared_ptr hoạt động cuối cùng bị hủy hoặc được đặt lại.
#include <memory>
std::shared_ptr<int> s1 = std::make_shared<int>(100);
std::shared_ptr<int> s2 = s1; // Allowed: increments the reference count
std::cout << s1.use_count() << std::endl; // Prints 2 (s1 and s2 share the resource)Hãy tự mình thử
Khai báo một std::unique_ptr<int> có tên ptr, khởi tạo nó với std::make_unique giữ giá trị 42. In giá trị không được tham chiếu của ptr bằng std::cout.
Hiển thị gợi ý
Sử dụng `std::unique_ptr<int> ptr = std::make_unique<int>(42);` và sau đó gửi `*ptr` đến luồng đầu ra.
Giải pháp khả dụng sau 3 lần thử
Khởi tạo std::shared_ptr<int> có tên ptr1 với giá trị 100 bằng cách sử dụng std::make_shared. Tạo một bản sao có tên ptr2 và in giá trị được trả về bởi ptr1.use_count() bằng std::cout.
Hiển thị gợi ý
Việc sao chép được thực hiện thông qua phép gán tiêu chuẩn: `ptr2 = ptr1;`. In `ptr1.use_count()` sẽ hiển thị 2.
Giải pháp khả dụng sau 3 lần thử