2016-07-15 3 views
9

make_shared<T>(...)は、(Tクラスのインスタンスと同じメモリブロック内に参照カウンタを割り当てることができる)メモリ割り当ての最適化を提供します。enable_shared_from_thisとmake_sharedは同じ最適化を提供しています

enable_shared_from_thisは同じ最適化を提供しますか?アカウントはsizeof(T)に服用しない場合

class T {}; 
... 
auto t = std::make_shared<T>(); 

:だから:

class T : std::enable_shared_from_this<T> {}; 
... 
auto t = std::shared_ptr<T>(new T); 

は同じです。

+5

2つは完全に直交しています。 'enable_shared_from_this'はあなたが既に*共有ポインタを持っているときに関係します。 –

+0

@KerrekSB私は、共有ポインタの実装で使用できるクラスにenable_shared_from_thisがいくつかのデータを追加するとします。私にとって最も簡単な方法は、enable_shared_from_thisの一部として参照の数を配置することです。これは、最初のケースでのメモリ割り当てを減らすのに役立ちます。 –

+0

私は "yes"と言ってしまいます。さもなければ、オブジェクト内部からrefcountブロックを取り出す方法がないからです。しかし、それはちょうど感傷です。 – Quentin

答えて

8

enable_shared_from_thisは同じ最適化を提供しますか?したがって:

番号標準の文言からわかるように、enable_shared_from_this<T>にはweak_ptr<T>というデータメンバーがあります。これは、参照カウントを含むコントロールブロックへのポインタを持つクラスにweak_ptr<T>を追加します。参照カウントは直接含まれません。参照カウントを含む制御ブロックは依然としてオブジェクトの外部に存在する。

参照カウントを含む制御ブロックは、オブジェクトを参照していた他のweak_ptrオブジェクトが制御ブロックにアクセスして、有効期限が切れていないかどうかを確認できるように、オブジェクトより長く存続する必要があります。

コントロールブロックがオブジェクトの内部にある場合、オブジェクトが破棄されたときに破棄され、ダングリングweak_ptrがオブジェクトの有効期限が切れているかどうかを安全に判断できません。理論的には、制御ブロックのメモリは割り当てられたままになり、依然として使用され、参照カウントは更新されましたが、たとえそのオブジェクトが破壊されても更新されましたが、それはかなり醜いようです(そして、オブジェクトはdelete明示的なデストラクタ呼び出しとメモリを解放する明示的なoperator delete呼び出しが必要です)。

所有者shared_ptrがカスタムディテクタまたはカスタムアロケータで作成されている場合は、埋め込みコントロールブロックを使用できません。これらのオブジェクトのサイズはあらかじめわかっていないためです。そのような場合には、さらにenable_shared_from_this<T>ベースクラスに埋め込まれたものに加えて、に加えて外部制御ブロックを割り当てる必要があり、さらに多くのスペースを浪費します。

+0

完璧な説明をありがとう! –

+0

これは非常に興味深い質問ですが、より多くの合併症がどのように機能するかについて考えると、 –

+0

インスタンスのmake_sharedメモリの場合、最後のweak_ptrが制御ブロックを指すまで解放できませんでした。しかし、enable_shared_from_thisとは対照的に、C++言語ポイントからはっきりと実装することができます(破壊されたオブジェクトを使用しないでください)。 –

関連する問題