2013-10-07 18 views
7

私が行った研究から、std::make_sharedstd::shared_ptrを構成するのに好ましい方法だと思われます。具体的には:std :: make_sharedを使用しない状況はありますか?

  1. 少なくとも2つを実行するnewを使用する場合と比較して、1回のメモリ割り当てしか実行しません。
  2. ctorがmake_sharedに渡すと、新しいものと同じように、リークしません。

私の質問は、私はshared_ptrのを望んでいることを、私はいつも使用make_shared、またはnewが好ましい場合がある必要がありますと仮定すると、ありますか?

+0

'shared_ptr'コンストラクタがスローすると' shared_ptr (new int) 'はメモリをリークしません。あなたの2番目のポイントは私に暗示しているようです。 – Simple

答えて

6

カウンタとオブジェクトは同じ割り当てを共有するため、同じ割り当て解除も共有されます。

カウンタは、最後のshared_ptrweak_ptrがなくなるまで保持する必要があります。長時間持続するweak_ptrの大きなオブジェクト(または多数の小さなオブジェクト)がある場合は、make_sharedを使用してshared_ptrを割り当てるとメモリ競合が発生する可能性があります。

第2に、ポインタまたはリソースハンドルを渡し、独自の処理機能を持つサードパーティAPIを使用している場合、make_sharedはいずれの場合でも使用することも適切でもありません。独自のmake_関数を作成することで、乱雑なディテールをそのままにして、この問題に対処し、例外コーナーケースも扱うことができます。

最後に、共有ポインタは素晴らしいですが、あまりにも強力です。かなり頻繁に私はunique_ptr、またはboost::scoped_ptr、または侵入参照カウントポインタなどを所有権を表すことを望んでいます。 shared_ptrは、状況が実際にがリソースを共有するの共有を含む場合にのみ使用する必要があります。「簡単」なので、スパゲッティコードに相当するリソースで終わる傾向があります。

+4

最後の段落のボーナスポイント。それは問題に直接訴えられていませんでしたが、それはこの文脈で十分に頻繁に言われることはありません。 –

2

動的に割り当てられたオブジェクトを返すレガシーコードを処理する必要があります。その場合は、std::shared_ptr<T> ctorをpointerパラメータとともに使用する必要があります。 std::make_sharedを使用することは好ましくありませんが、レガシーコードですべてのstd::shared_ptr<T>の優位性を使用することができます。

私は、これは直接newstd::shared_ptr<T> ctorのを使用して厳密に等価ではないことを知っているが、それはmake_sharedを利用することができませんstd::shared_ptr<T>の有効な使用例です。

0

(静的なファクトリメソッドからの)プライベートコンストラクタを持つクラスでmake_sharedを使って問題が発生しました。私はこれに簡単な解決策はないと思います。

+0

私はこれについて提起された欠陥があると思います。あなたは 'make_shared'を友人の機能にすることができるでしょうか?それがうまくいくかどうかは不明です。 – Simple

+0

私は 'private 'コンストラクタで' make_shared'を使うための回避策を作った:http://ideone.com/O93w6o – Simple

1

あなたの質問の解釈について少し不明です。私はそれがshared_ptr<T>を使用することが正当であると仮定しています。最初はshared_ptrを使用したくない理由で、唯一の理由はYakkです。

あなたがshared_ptrを構築するためにmake_sharedまたはallocate_sharedを使用することはできませんが、あなたは相当のctorを使用する必要がある状況があります:the ctors of shared_ptrでカスタム削除手段に渡す必要がある場合は、参照(3)と(4)。我々は他の誰かによって割り当てられたshared_ptrで裸のポインタを格納しているとき

0

私はいつもmake_shared使用、または は

make_sharedが好ましい新規症例があるべきでは許可されていません。それはpublicのコンストラクタにのみ呼び出すことができます。しかし、いくつかのコンパイラでは、make_shared like thisを使って保護されたコンストラクタにアクセスするという報告があります。