Tôi nghĩ rằng nó rất tò mò khi tôi phát hiện ra rằng tiêu chuẩn định nghĩa std::unique_ptr
và std::shared_ptr
theo hai cách hoàn toàn khác nhau liên quan đến Deleter mà con trỏ có thể sở hữu. Đây là tuyên bố từ cppreference::unique_ptr và cppreference::shared_ptr:Loại Deleter trong unique_ptr và shared_ptr
template<
class T,
class Deleter = std::default_delete<T>
> class unique_ptr;
template< class T > class shared_ptr;
Như bạn có thể thấy unique_ptr "tiết kiệm" các loại của các Deleter đối tượng làm mẫu đối số. Điều này cũng có thể được nhìn thấy trong cách Deleter được lấy từ con trỏ sau này:
// unique_ptr has a member function to retrieve the Deleter
template<
class T,
class Deleter = std::default_delete<T>
>
Deleter& unique_ptr<T, Deleter>::get_deleter();
// For shared_ptr this is not a member function
template<class Deleter, class T>
Deleter* get_deleter(const std::shared_ptr<T>& p);
Ai đó có thể giải thích lý do đằng sau sự khác biệt này? Tôi rõ ràng ủng hộ khái niệm cho unique_ptr
tại sao điều này không được áp dụng cho shared_ptr
? Ngoài ra, tại sao get_deleter
là một chức năng không phải là thành viên trong trường hợp sau?
Có người sẽ phải đào lên đề nghị ban đầu, nhưng võ đoán của tôi: Không có deleter như là đối số mẫu làm 'shared_ptr' dễ dàng hơn để sử dụng, nhưng bạn cần phải trả các chi phí loại tẩy xoá. Làm 'get_deleter' thành viên sẽ thực hiện viết mã generic tham gia một' shared_ptr 'tẻ nhạt hơn - bạn cần phải viết' get_deleter sp.template () 'thay vì' get_deleter (sp) '. Đây là lý do tại sao 'std :: get' là một người không phải là thành viên. –
Mở rộng một chút về những gì @ T.C. cho biết, một trong những mục tiêu thiết kế cho 'unique_ptr' là nó cần phải có (rất gần) zero overhead. Việc xóa kiểu của deleter là thuận tiện nhưng giới thiệu thời gian chạy trên không, vì vậy nó ít thích hợp hơn cho 'unique_ptr' hơn là' shared_ptr' – wakjah
Bạn cũng nên lưu ý rằng vì sự khác biệt đó, 'shared_ptr p = make_shared ()' làm điều đúng ngay cả khi 'Base' không có destructor ảo. [bằng chứng] (http://coliru.stacked-crooked.com/a/f3a50f90e00d4e58). –