Con trỏ weak
Một weak_ptr là một loại con trỏ thông minh trong C++ bổ sung mức độ gián tiếp và an toàn cho một con trỏ raw. Nó chủ yếu được sử dụng để phá vỡ các chu kỳ tham chiếu trong trường hợp hai đối tượng đã chia sẻ các con trỏ với nhau hoặc khi bạn cần một tham chiếu không sở hữu cho một đối tượng được shared_ptr quản lý.
Một weak_ptr không làm tăng số lượng tham chiếu của đối tượng mà nó trỏ tới, đây là điểm khác biệt quan trọng giữa weak_ptr và shared_ptr. Điều này đảm bảo rằng đối tượng sẽ bị xóa sau khi shared_ptr cuối cùng sở hữu nó vượt ra ngoài phạm vi, ngay cả khi vẫn còn có weak_ptrs tham chiếu đến nó.
Để sử dụng một weak_ptr, bạn phải chuyển đổi nó thành một shared_ptr bằng cách sử dụng hàm lock(), hàm này sẽ cố gắng tạo một shared_ptr mới để chia sẻ quyền sở hữu đối tượng. Nếu thành công, số lượng tham chiếu của đối tượng sẽ tăng lên và bạn có thể sử dụng shared_ptr được trả về để truy cập đối tượng một cách an toàn.
Đây là một ví dụ về việc sử dụng weak_ptr:
#include <iostream>
#include <memory>
class MyClass {
public:
void DoSomething() {
std::cout << "Doing something...\n";
}
};
int main() {
std::weak_ptr<MyClass> weak;
{
std::shared_ptr<MyClass> shared = std::make_shared<MyClass>();
weak = shared;
if(auto sharedFromWeak = weak.lock()) {
sharedFromWeak->DoSomething(); // Sử dụng an toàn đối tượng
std::cout << "Shared uses count: " << sharedFromWeak.use_count() << '\n'; // 2
}
}
// chia sẻ vượt quá phạm vi và đối tượng MyClass bị hủy
if(auto sharedFromWeak = weak.lock()) {
// Khối này sẽ không được thực thi vì đối tượng bị hủy
}
else {
std::cout << "Object has been destroyed\n";
}
return 0;
}
Trong ví dụ này, chúng tôi tạo một shared_ptr có tên là shared để quản lý một đối tượng MyClass. Bằng cách gán nó cho một weak_ptr có tên là weak, chúng tôi lưu trữ một tham chiếu không sở hữu cho đối tượng. Bên trong phạm vi bên trong, chúng tôi tạo một shared_ptr mới có tên sharedFromWeak bằng cách sử dụng weak.lock() để sử dụng đối tượng một cách an toàn. Sau phạm vi bên trong, đối tượng MyClass bị hủy do shared vượt quá phạm vi và bất kỳ nỗ lực nào khác để tạo shared_ptr từ weak sẽ thất bại vì đối tượng đã bị hủy.