51

make_shared<T>()を使用する代わりに使用することの欠点はありますかshared_ptr<T>(new T)

ブーストドキュメントの状態

特定のタイプのオブジェクトを作成し、それにshared_ptrを返すファクトリ関数に対するユーザーからの要求が繰り返されています。利便性とスタイルに加えて、このような関数は、オブジェクトとそれに対応する制御ブロックの両方に単一の割り当てを使用でき、shared_ptrの構築オーバーヘッドのかなりの部分を排除できるため、例外安全性とかなり高速です。これにより、shared_ptrに関する主な効率性の不満の1つが解消されます。

4

5 に答える 5

38

@deft_codeによって提示されたポイントに加えて、さらに弱いもの:

  • weak_ptr特定のオブジェクトに対するすべてのが終了した後に存続するを使用する場合shared_ptr、このオブジェクトのメモリは、最後のweak_ptrが終了するまで制御ブロックとともにメモリに存続します。つまり、オブジェクトは破棄されますが、最後のオブジェクトが破棄されるまで割り当てが解除されませんweak_ptr
于 2010-01-27T15:41:16.503 に答える
26

私は少なくとも2つ知っています。

  • 割り当てを管理する必要があります。それほど大きなものではありませんが、一部の古いAPIは、削除する必要のあるポインターを返すようなものです。
  • カスタム削除機能はありません。なぜこれがサポートされていないのかわかりませんが、サポートされていません。つまり、共有ポインタはバニラデリッターを使用する必要があります。

かなりの弱点。したがって、常にmake_sharedを使用するようにしてください。

于 2010-01-27T14:40:37.313 に答える
14

http://www.codesynthesis.com/~boris/blog/2010/05/24/smart-pointers-in-boost-tr1-cxx-x0/から

make_shared()実装のもう1つの欠点は、オブジェクトコードサイズが大きくなることです。この最適化の実装方法により、make_shared()で使用するオブジェクトタイプごとに、追加の仮想テーブルと一連の仮想関数がインスタンス化されます。

于 2011-05-10T21:43:17.540 に答える
8

また、make_sharedファクトリパターンとの互換性はありません。これはmake_shared、ファクトリ関数内での呼び出しがライブラリコードを呼び出すためです。ライブラリコードは、クラスのプライベートコンストラクタを呼び出すことができないためnew、アクセスできないライブラリコードを呼び出します(コンストラクタはプライベートである必要があります。工場出荷時のパターンに正しく従っています)。

于 2013-03-04T13:50:34.340 に答える
7

make sharedを使用すると、保持されているオブジェクトの割り当て割り当て解除がどのように行われるかを指定できません。

それが必要な場合は、std::allocate_shared<T>代わりに次を使用してください。

std::vector<std::shared_ptr<std::string>> avec; 
std::allocator<std::string> aAllocator;
avec.push_back(std::allocate_shared<std::string>(aAllocator,"hi there!"));

ベクトルはアロケータについて通知される必要がないことに注意してください!

カスタムアロケータを作成するには、こちらをご覧くださいhttps://stackoverflow.com/a/542339/1149664

于 2012-11-04T09:53:14.223 に答える