標準でstd::unique_ptr
とstd::shared_ptr
という2つの全く異なる方法でポインタが所有している可能性があることが判明したとき、私は非常に興味があると思った。ここでcppreference::unique_ptrとcppreference::shared_ptrからの宣言は次のとおりです。Deleter type in unique_ptr vs. shared_ptr
template<
class T,
class Deleter = std::default_delete<T>
> class unique_ptr;
template< class T > class shared_ptr;
あなたがunique_ptrをを見ることができるようにテンプレート引数としてDELETER・オブジェクトのタイプを「節約」。また、これはDELETERが後で上のポインタから取得された方法で見ることができます。
// 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);
誰かがこの違いの後ろに合理的に説明できますか?私は明らかにunique_ptr
のコンセプトを支持していますが、それはなぜshared_ptr
にも適用されませんか?また、なぜ後者の場合、get_deleter
が非メンバ関数になるのでしょうか?ここで
誰かが元の提案を掘り下げなければなりませんが、私の推測によれば、テンプレート引数としてDeleterを使用しないと、 'shared_ptr'が使いやすくなりますが、タイプ消去費用を支払う必要があります。 'get_deleter'をメンバにすると、' shared_ptr 'を使ってジェネリックコードを書くのがもっと面倒です。' get_deleter (sp) 'の代わりに' sp.template get_deleter () 'を書く必要があります。これは、 'std :: get'が非メンバである理由です。 –
@ T.Cについて少し拡張しています。 「unique_ptr」の設計目標の1つは、(ほとんど)ゼロのオーバーヘッドを持つべきであるということです。 Deleterの型を消去するのは便利ですが、消去からのランタイムオーバーヘッドを招くので、 'shared_ptr'よりも' unique_ptr'の方が適切ではありません。 – wakjah
その違いのため、 'shared_ptr p = make_shared 'Base'に仮想デストラクタがない場合でも正しいことを行います。 [証拠](http://coliru.stacked-crooked.com/a/f3a50f90e00d4e58)。 –