Thư viện chuẩn C ++ 11 có cung cấp bất kỳ tiện ích nào để chuyển đổi từ a std::shared_ptr
sang std::unique_ptr
, hoặc ngược lại không? Hoạt động này có an toàn không?
shared_ptr
.
Thư viện chuẩn C ++ 11 có cung cấp bất kỳ tiện ích nào để chuyển đổi từ a std::shared_ptr
sang std::unique_ptr
, hoặc ngược lại không? Hoạt động này có an toàn không?
shared_ptr
.
Câu trả lời:
std::unique_ptr
là cách C ++ 11 để thể hiện quyền sở hữu độc quyền, nhưng một trong những tính năng hấp dẫn nhất của nó là nó dễ dàng và hiệu quả chuyển đổi thànhstd::shared_ptr
.Đây là một phần quan trọng giải thích tại sao lại
std::unique_ptr
rất phù hợp với vai trò là kiểu trả về hàm gốc. Các hàm nhà máy không thể biết liệu người gọi có muốn sử dụng ngữ nghĩa quyền sở hữu độc quyền cho đối tượng mà họ trả lại hay không hay quyền sở hữu chung (tức làstd::shared_ptr
) sẽ phù hợp hơn. Bằng cách trả về astd::unique_ptr
, các nhà máy cung cấp cho người gọi một con trỏ thông minh hiệu quả nhất, nhưng chúng không cản trở người gọi thay thế nó bằng con trỏ linh hoạt hơn của nó.
std::shared_ptr
đểstd::unique_ptr
không được phép. Khi bạn đã chuyển quản lý suốt đời của một tài nguyên sang mộtstd::shared_ptr
, bạn sẽ không thay đổi suy nghĩ. Ngay cả khi số lượng tham chiếu là một, bạn không thể đòi lại quyền sở hữu tài nguyên để cóstd::unique_ptr
quản lý nó.Tham khảo: C ++ hiện đại hiệu quả. 42 CÁCH CỤ THỂ ĐỂ NÂNG CAO VIỆC SỬ DỤNG C ++ 11 VÀ C ++ 14 của bạn. Scott Meyers.
Trong ngắn hạn, bạn có thể dễ dàng và hiệu quả chuyển đổi a std::unique_ptr
thành std::shared_ptr
nhưng bạn không thể chuyển đổi std::shared_ptr
sang std::unique_ptr
.
Ví dụ:
std::unique_ptr<std::string> unique = std::make_unique<std::string>("test");
std::shared_ptr<std::string> shared = std::move(unique);
hoặc là:
std::shared_ptr<std::string> shared = std::make_unique<std::string>("test");
std::unique_ptr
cho a std::shared_ptr
.
Đã đưa ra unique_ptr u_ptr, hãy tạo shared_ptr s_ptr:
std::shared_ptr<whatever> s_ptr(u_ptr.release());
Đi theo con đường khác là không thực tế.
std::shared_ptr<whatever> s_ptr(std::move(u_ptr));
std::shared_ptr<whatever> s_ptr{std::move(u_ptr)};
Deleter
được lưu trữ bên trongunique_ptr