Các constructor của unique_ptr<T>
chấp nhận một con trỏ liệu đến một đối tượng kiểu T
(do đó, nó chấp nhận một T*
).
Trong ví dụ đầu tiên:
unique_ptr<int> uptr (new int(3));
Con trỏ là kết quả của một biểu thức new
, trong khi ở ví dụ thứ hai:
unique_ptr<double> uptr2 (pd);
Con trỏ được lưu trữ trong biến pd
.
Về mặt lý thuyết, không có gì thay đổi (bạn đang xây dựng một unique_ptr
từ một con trỏ thô), nhưng cách tiếp cận thứ hai là nguy hiểm hơn, vì nó sẽ cho phép bạn, ví dụ, để làm:
unique_ptr<double> uptr2 (pd);
// ...
unique_ptr<double> uptr3 (pd);
Như vậy có hai các con trỏ độc đáo có hiệu quả đóng gói cùng một đối tượng (do đó vi phạm ngữ nghĩa của con trỏ độc đáo).
Đây là lý do tại sao biểu mẫu đầu tiên để tạo con trỏ duy nhất tốt hơn, khi có thể. Lưu ý rằng trong C++ 14, chúng tôi sẽ có thể thực hiện:
unique_ptr<int> p = make_unique<int>(42);
Điều này rõ ràng hơn và an toàn hơn.Bây giờ liên quan đến nghi ngờ này của bạn:
What is also not clear to me, is how pointers, declared in this way will be different from the pointers declared in a "normal" way.
con trỏ thông minh có nghĩa vụ phải mô hình sở hữu đối tượng, và tự động chăm sóc phá hủy các đối tượng nhọn khi người cuối cùng (thông minh, sở hữu) con trỏ đến đối tượng mà rơi ra khỏi phạm vi. Bằng cách này bạn không cần phải nhớ làm delete
trên các đối tượng được phân bổ động - destructor của con trỏ thông minh sẽ làm điều đó cho bạn - cũng không phải lo lắng về việc bạn sẽ không dereference một con trỏ (lơ lửng) đến một đối tượng đã bị phá hủy đã:
{
unique_ptr<int> p = make_unique<int>(42);
// Going out of scope...
}
// I did not leak my integer here! The destructor of unique_ptr called delete
Bây giờ unique_ptr
là một con trỏ thông minh rằng các mô hình sở hữu độc đáo, có nghĩa là bất cứ lúc nào trong chương trình của bạn có phải chỉ một (sở hữu) con trỏ đến đối tượng nhọn - đó là lý do tại sao unique_ptr
không thể sao chép được. Miễn là bạn sử dụng con trỏ thông minh theo cách không phá vỡ hợp đồng ngầm mà họ yêu cầu bạn tuân thủ, bạn sẽ có bảo đảm rằng không có bộ nhớ nào bị rò rỉ và chính sách quyền sở hữu thích hợp cho đối tượng của bạn sẽ là thực thi. Con trỏ thô không cung cấp cho bạn đảm bảo này.
'new int (3)' trả về một con trỏ tới 'int' mới, giống như' pd' là một con trỏ tới 'double' mới. –