GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • cpprefjp - C++日本語リファレンス
  • GitHub Project

This view

  • Original page
  • New address

GeezerVison is showing cpprefjp.github.io — std::make_shared - cpprefjp C++日本語リファレンス

  1. リファレンス
  2. memory
  3. make_shared

最終更新日時: 2026年09月11日 13時06分31秒 (JST)
Akira Takahashi が更新

履歴 編集

function template
<memory>

std::make_shared(C++11)

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

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

  template <class T>
  shared_ptr<T>
    make_shared();                            // (3) C++20
  template <class T>
  constexpr shared_ptr<T>
    make_shared();                            // (3) C++26

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

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

概要

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

効果

型Tのオブジェクトにメモリを割り当てる(TがU[]の場合はremove_extent_t<T>型の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) : デフォルトの初期値を持つ、remove_extent_t<T>型のN個の要素からなる配列へのshared_ptrを返す。Tの形式がU[]の場合にのみ、このオーバーロードはオーバーロード解決に関与する。
  • (3) : デフォルトの初期値を持つT型のオブジェクトへのshared_ptrを返す。このオーバーロードは、TがU[N]の形式の場合にのみオーバーロード解決に関与する。
  • (4) : remove_extent_t<T>型のN個の要素からなる配列へのshared_ptrを返す。各配列要素の初期値は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() を使用する。

この関数では初期値が指定されない場合に確保した領域にオブジェクトが値初期化され構築される。値初期化においては、組み込み型は0相当の値で初期化され、クラス型はデフォルトコンストラクタによって初期化される。この関数でメモリを確保した後ですぐに別の値で上書きしている場合、代わりにmake_shared_for_overwrite()を使用することで初期化のオーバーヘッドを削減できる可能性がある。

例

#include <memory>
#include <iostream>

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

出力

42

バージョン

言語

  • C++11

処理系

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

関連項目

  • std::allocate_shared()
  • std::make_shared_for_overwrite()
  • std::allocate_shared_for_overwrite()

参照

  • N2351 Improving shared_ptr for C++0x, Revision 2
  • std::make_shared から private コンストラクタを呼び出す - 野良C++erの雑記帳
  • P0674R1 Extending make_shared to support arrays
  • P3037R6 constexpr std::shared_ptr and friends
  • LWG Issue 866. Qualification of placement new-expressions
    • C++11で、make_sharedが要素を構築する際に使用する配置newが::newと修飾された。修飾がないと、要素型がクラススコープのoperator newをオーバーロードしている場合にそちらが選ばれてしまい、対応するoperator deleteが呼ばれず不整合を起こすため
  • LWG Issue 2696. Interaction between make_shared and enable_shared_from_this is underspecified
    • C++17で、make_shared/allocate_sharedが呼び出すコンストラクタもshared_from_thisを有効にすることが明確化された
    • この修正は欠陥報告(DR)であり、C++11以降に遡及して適用される。元の規定はpublicなコンストラクタについてのみshared_from_thisの有効化を述べており、これらの関数が使う非publicなコンストラクタについては未規定だったが、処理系は当初から有効化していたため
  • LWG Issue 3005. Destruction order of arrays by make_shared/allocate_shared only recommended?
    • C++20で、配列要素の破棄順が非規範的な推奨から規範的要件に格上げされ、元の構築順の逆順で破棄されることが明確化された
  • LWG Issue 3008. make_shared (sub)object destruction semantics are not specified
    • C++20で、生成した(サブ)オブジェクトの破棄方法(make_sharedは式pv->~U()による破棄)が明示的に規定された
  • LWG Issue 4451. make_shared should not refer to a type U[N] for runtime N
    • C++26で、Nが実行時の値である配列版において、結果を「U[N]型のオブジェクト」ではなく「remove_extent_t<T>型のN要素の配列」と表現するよう文言が修正された(実行時サイズのU[N]は妥当な型ではないため)
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.