Hàm tạo của unique_ptr<T>
chấp nhận một con trỏ thô tới một đối tượng có kiểu T
(vì vậy, nó chấp nhận a T*
).
Trong ví dụ đầu tiên:
unique_ptr<int> uptr (new int(3));
Con trỏ là kết quả của một new
biểu thức, trong khi ở ví dụ thứ hai:
unique_ptr<double> uptr2 (pd);
Con trỏ được lưu trữ trong pd
biến.
Về mặt khái niệm, không có gì thay đổi (bạn đang xây dựng một unique_ptr
con trỏ thô), nhưng cách tiếp cận thứ hai có khả năng nguy hiểm hơn, vì ví dụ, nó sẽ cho phép bạn làm:
unique_ptr<double> uptr2 (pd);
unique_ptr<double> uptr3 (pd);
Do đó có hai con trỏ duy nhất đóng gói hiệu quả cùng một đối tượng (do đó vi phạm ngữ nghĩa của một con trỏ duy nhất ).
Đây là lý do tại sao biểu mẫu đầu tiên để tạo một con trỏ duy nhất sẽ tốt hơn khi có thể. Lưu ý rằng trong C ++ 14, chúng ta sẽ có thể thực hiện:
unique_ptr<int> p = make_unique<int>(42);
Cái nào vừa rõ ràng vừa an toàn hơn. Bây giờ liên quan đến nghi ngờ này của bạn:
Điều mà tôi cũng không rõ là con trỏ được khai báo theo cách này sẽ khác với các con trỏ được khai báo theo cách "bình thường" như thế nào.
Con trỏ thông minh được cho là mô hình hóa quyền sở hữu đối tượng và tự động xử lý việc hủy đối tượng được trỏ khi con trỏ cuối cùng (thông minh, sở hữu) đến đối tượng đó nằm ngoài phạm vi.
Bằng cách này, bạn không phải nhớ thực hiện delete
trên các đối tượng được cấp phát động - trình hủy của con trỏ thông minh sẽ làm điều đó cho bạn - cũng như không phải lo lắng về việc bạn sẽ không tham khảo một con trỏ (treo lơ lửng) tới một đối tượng đã bị hủy:
{
unique_ptr<int> p = make_unique<int>(42);
}
Bây giờ unique_ptr
là một con trỏ thông minh mô hình quyền sở hữu duy nhất, có nghĩa là bất kỳ lúc nào trong chương trình của bạn sẽ chỉ có một con trỏ (sở hữu) đến đối tượng trỏ - đó là lý do tại sao unique_ptr
không thể sao chép.
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à chúng yêu cầu bạn tuân thủ, bạn sẽ có đảm bảo rằng bộ nhớ sẽ không bị rò rỉ và chính sách sở hữu thích hợp cho đối tượng của bạn sẽ được thực thi. Con trỏ thô không cung cấp cho bạn sự đảm bảo này.
new int(3)
trả về một con trỏ đến cái mớiint
, giống nhưpd
một con trỏ đến cái mớidouble
.