簡體   English   中英

為什么unique_ptr在shared_ptr只占用一個時需要兩個模板參數?

[英]Why does unique_ptr take two template parameters when shared_ptr only takes one?

unique_ptrshared_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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM