web-dev-qa-db-ja.com

newを使用したstd :: make_uniqueとstd :: unique_ptrの違い

std::make_uniqueにはstd::make_sharedのような効率上の利点がありますか?

std::unique_ptrを手動で構築する場合と比較して:

std::make_unique<int>(1);         // vs
std::unique_ptr<int>(new int(1));
111
NFRCR

make_uniqueの背後にある動機は、主に2つあります。

  • make_uniqueは一時的なものを作成しても安全ですが、newを明示的に使用すると、名前のない一時的なものを使用しないというルールを覚えておく必要があります。

    foo(make_unique<T>(), make_unique<U>()); // exception safe
    
    foo(unique_ptr<T>(new T()), unique_ptr<U>(new U())); // unsafe*
    
  • make_uniqueの追加は、最後にunique_ptrを作成する場合を除いて、newを使用しないという以前のルールではなく、newを使用しないことを人々に伝えることができることを意味します「。

3番目の理由もあります。

  • make_uniqueは、冗長な型の使用を必要としません。 unique_ptr<T>(new T())-> make_unique<T>()

make_sharedを使用する方法で実行時の効率を改善することには、理由がありません(2番目の割り当てを回避するため、ピークメモリ使用量が高くなる可能性があります)。

* C++ 17には、これがもはや安全ではないことを意味するルール変更が含まれることが予想されます。 C++委員会のペーパー P0400R および P0145R を参照してください。

129
bames53

std::make_uniquestd::make_sharedには2つの理由があります。

  1. そのため、テンプレートタイプの引数を明示的にリストする必要はありません。
  2. std::unique_ptrまたはstd::shared_ptrコンストラクターの使用に対する追加の例外安全性。 (注セクションを参照してください ここ 。)

実行時の効率に関するものではありません。制御ブロックとTが一度に割り当てられるという点は少しありますが、これらの機能が存在することのほうがボーナスであり、モチベーションが低いと思います。

11
Timothy Shields

std::unique_ptr(new A())の代わりにstd::shared_ptr(new A())またはstd::make_*()を直接使用する必要がある理由は、現在のスコープ外のクラスAのコンストラクターにアクセスできないためです。

6