make_shared<T>()
を使用する代わりにshared_ptr<T>(new T)
を使用することの欠点はありますか。
ブーストドキュメント 状態
特定のタイプのオブジェクトを作成し、それにshared_ptrを返すファクトリ関数に対するユーザーからの要求が繰り返されています。利便性とスタイルに加えて、このような関数は、オブジェクトとそれに対応する制御ブロックの両方に単一の割り当てを使用でき、shared_ptrの構築オーバーヘッドのかなりの部分を排除できるため、例外安全性とかなり高速です。これにより、shared_ptrに関する主要な効率性の不満の1つが解消されます。
私は少なくとも2つ知っています。
かなりの弱点。したがって、常にmake_sharedを使用するようにしてください。
@deft_codeによって提示されたポイントに加えて、さらに弱いもの:
weak_ptr
sが終了した後に存続するshared_ptr
sを使用する場合、このオブジェクトのメモリは、最後のweak_ptrが終了するまで制御ブロックとともにメモリに存続します。つまり、オブジェクトは破棄されますが、最後のweak_ptr
が破棄されるまで割り当てが解除されません。から http://www.codesynthesis.com/~boris/blog/2010/05/24/smart-pointers-in-boost-tr1-cxx-x0/
make_shared()実装のもう1つの欠点は、オブジェクトコードサイズが大きくなることです。この最適化の実装方法により、make_shared()で使用するオブジェクトタイプごとに、追加の仮想テーブルと一連の仮想関数がインスタンス化されます。
さらに、make_shared
はファクトリパターンと互換性がありません。これは、ファクトリ関数内でmake_shared
を呼び出すと、ライブラリコードが呼び出され、ライブラリコードがアクセスできないnew
を呼び出すためですクラスを呼び出すことができないため)プライベートコンストラクター(ファクトリパターンに正しく従う場合、コンストラクターはプライベートである必要があります)。
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