[英]Why does std::shared_ptr<T> = std::unique_ptr<T[]> compile, while std::shared_ptr<T[]> = std::unique_ptr<T[]> does not?
[英]Why does unique_ptr take two template parameters when shared_ptr only takes one?
unique_ptr
和shared_ptr
接受自定義析構函數來調用它們擁有的對象。 但在案件unique_ptr
,析構函數的類的模板參數傳遞,而類型shared_ptr
的定制析構函數將被指定為構造函數的模板參數。
template <class T, class D = default_delete<T>>
class unique_ptr
{
unique_ptr(T*, D&); //simplified
...
};
和
template<class T>
class shared_ptr
{
template<typename D>
shared_ptr(T*, D); //simplified
...
};
我不明白為什么會有這樣的差異。 需要什么?
如果您將deleter作為模板參數提供(如在unique_ptr
),則它是該類型的一部分,您不需要在此類型的對象中存儲任何其他內容。 如果將deleteter作為構造函數的參數傳遞(如在shared_ptr
),則需要將其存儲在對象中。 這是額外靈活性的代價,因為您可以為相同類型的對象使用不同的刪除器。
我猜這就是原因: unique_ptr
應該是非常輕量級的對象,零開銷。 使用每個unique_ptr
存儲刪除器可以使其大小加倍。 因為人們會使用舊的原始指針代替,這是錯誤的。
另一方面, shared_ptr
不是那么輕量級,因為它需要存儲引用計數,因此存儲自定義刪除器看起來也很好。
不同類型的共享指針可以共享同一對象的所有權。 請參閱std::shared_ptr::shared_ptr
overload(8) 。 唯一指針不需要這樣的機制,因為它們不共享 。
template< class Y >
shared_ptr( const shared_ptr<Y>& r, element_type* ptr ) noexcept;
如果你沒有對刪除器進行類型擦除,你將無法使用這樣的shared_ptr<T, Y_Deleter>
作為shared_ptr<T>
,這將使它基本無用。
你為什么要這么過載?
考慮
struct Member {};
struct Container { Member member };
如果你想讓Container
保持活着,你可以使用Member
std::shared_ptr<Container> pContainer = /* something */
std::shared_ptr<Member> pMember(pContainer, &pContainer->member);
並且只需要保持pMember
(也許把它放到std::vector<std::shared_ptr<Member>>
)
或者,使用過載(9)
template< class Y >
shared_ptr( const shared_ptr<Y>& r ) noexcept;
// Only exists if Y* is implicitly convertible to T*
你可以進行多態共享
struct Base {};
struct Derived : Base {};
void operate_on_base(std::shared_ptr<Base>);
std::shared_ptr<Derived> pDerived = /* something*/
operate_on_base(pDerived);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.