最終更新日時(UTC):
が更新

履歴 編集

function
<memory>

std::make_shared(C++11)

namespace std {
  template <class T, class... Args>
  shared_ptr<T> make_shared(Args&&... args);                        // (1)

  template <class T>
  shared_ptr<T> make_shared(size_t N);                              // (2) C++20 から

  template <class T>
  shared_ptr<T> make_shared();                                      // (3) C++20 から

  template <class T>
  shared_ptr<T> make_shared(size_t N, const remove_extent_t<T>& u); // (4) C++20 から

  template <class T>
  shared_ptr<T> make_shared(const remove_extent_t<T>& u);           // (5) C++20 から
}

概要

shared_ptr オブジェクトを構築する。

効果

Tのオブジェクトにメモリを割り当てる(TU[]の場合はU[N]Nはそれぞれのオーバーロードで指定された引数から決定される)。

オブジェクトは、それぞれのオーバーロードで指定された引数から初期化される。

例外がスローされた場合、関数は効果がない。

配列型Uのオブジェクトが(同じ型の)uの初期値を持つように指定されている場合、これは、オブジェクトの各配列要素が初期値としてuからの対応する要素を持つことを意味すると解釈される。

配列タイプのオブジェクトがデフォルトの初期値を持つように指定されている場合、これはオブジェクトの各配列要素がデフォルトの初期値を持つことを意味すると解釈される。

非配列型Uの(サブ)オブジェクトが、vまたはU(l ...)の初期値を持つように指定されている場合(l...はコンストラクター引数のリスト)、make_sharedは、式::new (pv) U(v)または::new (pv) U(l...)を使用して、この(サブ)オブジェクトを初期化する。ここで、pvの型はvoid*であり、型Uのオブジェクトを保持するのに適したストレージを指す。

非配列型Uの(サブ)オブジェクトがデフォルトの初期値を持つように指定されている場合、この関数は、式 ::new (pv) U()を使用してこの(サブ)オブジェクトを初期化する。void*は型Uのオブジェクトを保持するのに適したストレージを指す。

配列要素は、アドレスの昇順で初期化される。

戻り値によって管理されるオブジェクトのlifetimeが終了するか、配列要素の初期化が例外をスローすると、初期化された要素は元の構造の逆の順序で破棄される。

この関数によって初期化された非配列型Uの(サブ)オブジェクトを破棄する場合、式pv->~U()によって破棄される。pvは型Uのオブジェクトを指す。

  • (1) : 初期値T(forward<Args>(args)...)を持つ型Tのオブジェクトへのshared_ptrを返す。Tが配列型でない場合にのみ、このオーバーロードはオーバーロード解決に関与する。この関数によって呼び出されるshared_ptrコンストラクターは、型Tの新しく構築されたオブジェクトのアドレスでshared_from_thisを有効にする。
  • (2) : デフォルトの初期値を持つU[N]型のオブジェクトへのshared_ptrを返す。ここで、Uremove_extent_t<T>である。Tの形式がU[]の場合にのみ、このオーバーロードはオーバーロード解決に関与する。
  • (3) : デフォルトの初期値を持つT型のオブジェクトへのshared_ptrを返す。このオーバーロードは、TU[N]の形式の場合にのみオーバーロード解決に関与する。
  • (4) : U[N]型のオブジェクトへのshared_ptrを返す。ここで、Uremove_extent_t<T>であり、各配列要素の初期値はuである。Tの形式がU[]の場合にのみ、このオーバーロードはオーバーロード解決に関与する。
  • (5) : 型Tのオブジェクトへのshared_ptrを返す。ここで、型remove_extent_t<T>の各配列要素は初期値uを持つ。

戻り値

Tに対する shared_ptr<T>オブジェクトを生成し返却する。
このとき、args... で受け取った引数リストを型 Tのコンストラクタへ渡してshared_ptr<T>型のオブジェクトを生成する。

事後条件

r.get() != 0 && r.use_count() == 1, ここで、r は戻り値である。

例外

bad_alloc、またはallocateまたはオブジェクトの初期化からスローされた例外。

備考

shared_ptr<T>(new T(args...)); というように、コンストラクタを呼び出す方法でもshared_ptrオブジェクトを構築できる。しかしこの方法では、以下の2つのメモリ確保が必要になり、効率がよくない:

  • ユーザーによるオブジェクトの生成
  • 内部的な参照カウンタの生成

make_shared() 内部的にオブジェクトを生成するため、オブジェクトの生成と参照カウンタの生成を、1つの大きなブロックとしてメモリを確保するため、より効率的になる。

メモリの確保にユーザー定義のアロケータを使用したい場合には、 allocate_shared() を使用する。

#include <memory>
#include <iostream>

int main() {
  std::shared_ptr<int> sp = std::make_shared<int>();
  if(sp) {
    std::cout << *sp << std::endl;
  }
}

出力

42

バージョン

言語

  • C++11

処理系

  • Clang: 3.2, 3.3
  • GCC: 4.4, 4.7.3, 4.8.2
  • ICC: ??
  • Visual C++: 2010, 2012, 2013
    • 2010〜2012 でも使用可能だが、コンパイラが可変引数テンプレートに対応していないため、最大10個の引数を受け取れる形で実装されている。

関連項目

参照