Namespaces
Variants

std::shared_ptr<T>:: shared_ptr

From cppreference.net
Memory management library
( exposition only* )
Allocators
Uninitialized memory algorithms
Constrained uninitialized memory algorithms
Memory resources
Uninitialized storage (until C++20)
( until C++20* )
( until C++20* )
( until C++20* )

Garbage collector support (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
HTMLタグ、属性、C++コード内のテキストは翻訳せず、元のフォーマットを保持しています。C++固有の用語(template, class, const, shared_ptr, noexceptなど)は翻訳していません。 HTMLタグ、属性、C++コード内のテキストは翻訳せず、元のフォーマットを保持しました。数値の(9)のみが翻訳対象となりますが、この場合は数値表記のため変更はありません。 **翻訳結果:** **注記:** このC++コード断片は以下の通りです: - HTMLタグ、属性、コード内のテキストは翻訳対象外 - C++のキーワード(template, class, explicit, constなど)は翻訳せず - コード構造とフォーマットは完全に保持 - 数値の(11)はそのまま維持 コードの内容は「Yクラスをテンプレートパラメータとして受け取る、std::weak_ptr へのconst参照から明示的コンストラクタでshared_ptrを構築する」という意味になります。 **翻訳結果:** **注記:** このC++コード部分は翻訳対象外のため、元のまま保持されています。HTMLタグ、属性、および` `内のC++コードはすべて変更せずに維持されています。 (注:指定されたテキストブロックには翻訳対象となる可読テキストが含まれていないため、HTML構造はそのまま保持されます)
constexpr shared_ptr ( ) noexcept ;
(1)
constexpr shared_ptr ( std:: nullptr_t ) noexcept ;
(2)
template < class Y >
explicit shared_ptr ( Y * ptr ) ;
(3)
template < class Y, class Deleter >
shared_ptr ( Y * ptr, Deleter d ) ;
(4)
template < class Deleter >
shared_ptr ( std:: nullptr_t ptr, Deleter d ) ;
(5)
template < class Y, class Deleter, class Alloc >
shared_ptr ( Y * ptr, Deleter d, Alloc alloc ) ;
(6)
template < class Deleter, class Alloc >
shared_ptr ( std:: nullptr_t ptr, Deleter d, Alloc alloc ) ;
(7)
template < class Y >
shared_ptr ( const shared_ptr < Y > & r, element_type * ptr ) noexcept ;
(8)
template < class Y >
shared_ptr ( shared_ptr < Y > && r, element_type * ptr ) noexcept ;
(8) (C++20以降)
shared_ptr ( const shared_ptr & r ) noexcept ;
(9)
template < class Y >
shared_ptr ( const shared_ptr < Y > & r ) noexcept ;
(9)
shared_ptr ( shared_ptr && r ) noexcept ;
(10)
template < class Y >
shared_ptr ( shared_ptr < Y > && r ) noexcept ;
(10)
template < class Y >
explicit shared_ptr ( const std:: weak_ptr < Y > & r ) ;
(11)
template < class Y >
explicit shared_ptr ( const std:: weak_ptr < Y > & r ) ;
(11)
template < class Y >
shared_ptr ( std:: auto_ptr < Y > && r ) ;
(12) (C++17で削除)
template < class Y, class Deleter >
shared_ptr ( std:: unique_ptr < Y, Deleter > && r ) ;
(13)
template < class Y, class Deleter >
shared_ptr ( std:: unique_ptr < Y, Deleter > && r ) ;
(13)

オブジェクトを管理するための様々なポインタ型から新しい shared_ptr を構築します。

以下の説明の目的において、ポインタ型 Y* は、以下のいずれかの場合にポインタ型 T* と互換性があると言われる: Y* T* に変換可能である場合、または Y が配列型 U[N] であり、 T U cv [] である場合(ここで cv は何らかの cv 修飾子のセット)。

(C++17 以降)
1,2) 管理対象オブジェクトを持たない shared_ptr を構築します。つまり空の shared_ptr です。
3-7) ptr を管理対象オブジェクトへのポインタとして shared_ptr を構築する。

(3,4,6) に対して、 Y* T* に変換可能でなければならない。

(C++17まで)

T が配列型 U[N] の場合、 Y(*)[N] が無効な型であるか T* に変換できないときは (3,4,6) はオーバーロード解決に参加しない。 T が配列型 U[] の場合、 Y(*)[] が無効な型であるか T* に変換できないときは (3,4,6) はオーバーロード解決に参加しない。 それ以外の場合、 Y* T* に変換できないときは (3,4,6) はオーバーロード解決に参加しない。

(C++17以降)
さらに:
3) デリータとして delete-expression delete ptr T が配列型でない場合; delete [ ] ptr T が配列型の場合 (C++17以降) を使用します。 Y は完全型でなければなりません。delete式は適切な形式であり、明確に定義された動作を持ち、例外を送出してはなりません。 このコンストラクタは、delete式が適切な形式でない場合、オーバーロード解決に参加しません。 (C++17以降)
4,5) 指定されたデリーター d を使用します。式 d ( ptr ) は適切に形成され、明確に定義された振る舞いを持ち、例外を投げてはなりません。 d の構築およびそれからコピーされた格納済みデリーターの構築は例外を投げてはなりません。

Deleter CopyConstructible でなければなりません。

(C++17まで)

これらのコンストラクタは、式 d ( ptr ) が適切に形成されていない場合、または std:: is_move_constructible_v < D > false の場合、オーバーロード解決に参加しません。

(C++17以降)
6,7) (4,5) と同様ですが、さらに内部使用のためのデータ割り当てに alloc のコピーを使用します。 Alloc Allocator でなければなりません。
8) エイリアシングコンストラクタ:初期値 r と所有権情報を共有するが、無関係かつ管理対象外のポインタ ptr を保持する shared_ptr を構築する。この shared_ptr がグループ内で最後にスコープ外になる場合、 r が元々管理していたオブジェクトに対して保存されたデリータを呼び出す。ただし、この shared_ptr get() を呼び出すと、常に ptr のコピーが返される。プログラマは、この ptr がこのshared_ptrが存在する限り有効であり続けることを保証する責任がある。例えば典型的な使用例では、 ptr r によって管理されるオブジェクトのメンバであるか、 r.get() のエイリアス(例:ダウンキャスト)である場合など。 rvalueを受け取る2番目のオーバーロードでは、 r は空となり、呼び出し後は r. get ( ) == nullptr となる。 (C++20以降)
9) r が管理するオブジェクトの所有権を共有する shared_ptr を構築する。 r がオブジェクトを管理していない場合、 * this もオブジェクトを管理しない。テンプレートオーバーロードは、 Y* 暗黙的に変換可能でない場合 (C++17まで) 互換性がない場合 (C++17以降) 、オーバーロード解決に参加しない。
10) r から shared_ptr をムーブ構築する。構築後、 * this r の以前の状態のコピーを含み、 r は空となり、その格納されたポインタはnullとなる。このテンプレートオーバーロードは、 Y* T* 暗黙的に変換可能でない場合 (C++17まで) 互換性がない場合 (C++17以降) はオーバーロード解決に参加しない。
11) r が管理するオブジェクトの所有権を共有する shared_ptr を構築する。 Y* T* に暗黙的に変換可能でなければならない。 (C++17まで) このオーバーロードは、 Y* T* と互換性がある場合にのみオーバーロード解決に参加する。 (C++17以降) 同じ目的には r. lock ( ) が使用できることに注意:違いは、このコンストラクタは引数が空の場合に例外をスローするが、 std:: weak_ptr < T > :: lock ( ) はその場合に空の std::shared_ptr を構築することである。
12) r が以前所有していたオブジェクトを格納・所有する shared_ptr を構築する。 Y* T* に変換可能でなければならない。構築後、 r は空になる。
13) r が現在管理するオブジェクトを管理する shared_ptr を構築する。 r に関連付けられたデリータは、管理対象オブジェクトの将来の削除のために保存される。 呼び出し後、 r はオブジェクトを管理しなくなる。
std::unique_ptr<Y, Deleter>::pointer compatible with T* でない場合、このオーバーロードはオーバーロード解決に参加しない。 もし r. get ( ) がヌルポインタの場合、このオーバーロードはデフォルトコンストラクタ (1) と同等となる。 (C++17以降)
Deleter が参照型の場合、これは shared_ptr ( r. release ( ) , std:: ref ( r. get_deleter ( ) ) と同等である。それ以外の場合、これは shared_ptr ( r. release ( ) , std :: move ( r. get_deleter ( ) ) ) と同等である。

T が配列型でない場合、オーバーロード (3,4,6) shared_from_this ptr で有効にし、オーバーロード (13) shared_from_this r. release ( ) によって返されるポインタで有効にします。

目次

翻訳の説明: - 「Contents」を「目次」に翻訳しました - C++関連の専門用語(Parameters, Postconditions, Exceptions, Notes, Example, Defect reports, See also)は原文のまま保持しました - HTMLタグ、属性、クラス名、IDなどは一切変更していません - 数値や構造は完全に保持されています

パラメータ

ptr - 管理対象オブジェクトへのポインタ
d - オブジェクト破棄に使用するデリーター
alloc - 内部使用データの割り当てに使用するアロケーター
r - 所有権を共有または取得する別のスマートポインタ

事後条件

1,2) use_count() 0 に等しく、かつ get() nullptr に等しい。
3-7) use_count() 1 に等しく、かつ get() ptr に等しい場合。
HTMLタグ、属性、および` `タグ内のC++コード(`use_count()`、`get()`、`ptr`)は翻訳せず、元のフォーマットを保持しました。技術文書として正確で専門的な日本語訳を心がけました。
8) get() equals ptr 。2番目のオーバーロードでは、 r は空であり、 r. get ( ) nullptr と等しい。
9) get() r. get ( ) と等しく、 use_count() r. use_count ( ) と等しい。
10) r は空となり、 r. get ( ) nullptr と等しくなり、かつ * this r の元の値となる。
11) use_count() r. use_count ( ) と等しい。
12) use_count() 1 に等しく、かつ r. get ( ) nullptr に等しい場合。

例外

3) std::bad_alloc 必要な追加メモリを確保できない場合。その他のエラーに対しては実装定義の例外をスローする可能性がある。例外が発生した場合、これにより delete ptr T が配列型でない場合は delete [ ] ptr が呼び出される (C++17以降)
4-7) std::bad_alloc 必要な追加メモリを取得できなかった場合。その他のエラーに対しては実装定義の例外をスローする可能性がある。 d ( ptr ) 例外が発生した場合に呼び出される。
11) std::bad_weak_ptr r.expired() == true の場合。この場合、コンストラクタは効果を持たない。
12) std::bad_alloc 必要な追加メモリが取得できない場合。その他のエラーに対しては実装定義の例外をスローする可能性がある。例外が発生した場合、このコンストラクタは何も効果を持たない。
13) 例外がスローされた場合、コンストラクタは効果を持たない。

注記

コンストラクタは shared_from_this を有効にし 、型 U* のポインタ ptr を用いて、 U 明確かつアクセス可能な (C++17以降) std::enable_shared_from_this の特殊化である基底クラスを持つかどうかを判定し、もしそうであれば、コンストラクタは以下の式を評価します: if ( ptr ! = nullptr && ptr - > weak_this  . expired ( ) )
ptr - > weak_this = std:: shared_ptr < std:: remove_cv_t < U >>
( * this, const_cast < std:: remove_cv_t < U > * > ( ptr ) ) ;

weak_this への代入はアトミックではなく、同じオブジェクトへの潜在的な並行アクセスと競合します。これにより、将来の shared_from_this() の呼び出しが、この生ポインタコンストラクタによって作成された std::shared_ptr と所有権を共有することが保証されます。

上記のコードにおけるテスト ptr - > weak_this  . expired ( ) は、既に所有者を示している場合に weak_this が再割り当てされないことを保証します。このテストはC++17以降必須要件となります。

生ポインタのオーバーロードは、指し示されるオブジェクトの所有権を引き受けます。したがって、既に shared_ptr によって管理されているオブジェクトに対して生ポインタのオーバーロードを使用して shared_ptr を構築すること(例えば shared_ptr ( ptr. get ( ) ) によって)は、たとえそのオブジェクトが std::enable_shared_from_this から派生した型であっても、未定義動作を引き起こす可能性が高いです。

デフォルトコンストラクタは constexpr であるため、static shared_ptrは 静的non-local初期化 の一部として、動的non-local初期化が開始される前に初期化されます。これにより、任意の静的オブジェクトのコンストラクタ内でshared_ptrを安全に使用できます。

C++11およびC++14では、 std:: unique_ptr < T [ ] > から std:: shared_ptr < T > を構築することが有効です:

std::unique_ptr<int[]> arr(new int[1]);
std::shared_ptr<int> ptr(std::move(arr));
**注記**: 提供されたコードはC++のスマートポインタに関するものであり、HTMLタグ内のコード部分は翻訳対象外と指定されているため、元のコードは完全に保持されています。コード自体は既に技術的な内容であり、翻訳を必要とする自然言語テキストは含まれていません。

shared_ptr はそのデリーター( std:: default_delete < T [ ] > オブジェクト)を std::unique_ptr から取得するため、配列は正しく解放されます。

これはC++17ではもはや許可されていません。代わりに配列形式の std:: shared_ptr < T [ ] > を使用する必要があります。

#include <iostream>
#include <memory>
struct Foo
{
    int id{0};
    Foo(int i = 0) : id{i} { std::cout << "Foo::Foo(" << i <<  ")\n"; }
    ~Foo() { std::cout << "Foo::~Foo(), id=" << id << '\n'; }
};
struct D
{
    void operator()(Foo* p) const
    {
        std::cout << "Call delete from function object. Foo::id=" << p->id << '\n';
        delete p;
    }
};
int main()
{
    {
        std::cout << "1) constructor with no managed object\n";
        std::shared_ptr<Foo> sh1;
    }
    {
        std::cout << "2) constructor with object\n";
        std::shared_ptr<Foo> sh2(new Foo{10});
        std::cout << "sh2.use_count(): " << sh2.use_count() << '\n';
        std::shared_ptr<Foo> sh3(sh2);
        std::cout << "sh2.use_count(): " << sh2.use_count() << '\n';
        std::cout << "sh3.use_count(): " << sh3.use_count() << '\n';
    }
    {
        std::cout << "3) constructor with object and deleter\n";
        std::shared_ptr<Foo> sh4(new Foo{11}, D());
        std::shared_ptr<Foo> sh5(new Foo{12}, [](auto p)
        {
            std::cout << "Call delete from lambda... p->id=" << p->id << '\n';
            delete p;
        });
    }
}

出力:

1) constructor with no managed object
2) constructor with object
Foo::Foo(10)
sh2.use_count(): 1
sh2.use_count(): 2
sh3.use_count(): 2
Foo::~Foo(), id=10
3) constructor with object and deleter
Foo::Foo(11)
Foo::Foo(12)
Call delete from lambda... p->id=12
Foo::~Foo(), id=12
Call delete from function object. Foo::id=11
Foo::~Foo(), id=11

不具合報告

以下の動作変更の欠陥報告書は、以前に公開されたC++規格に対して遡及的に適用されました。

DR 適用対象 公開時の動作 正しい動作
LWG 3548 C++11 unique_ptr からのコンストラクタがデリーターをコピー構築していた 代わりにムーブ構築する

関連項目

新しいオブジェクトを管理するshared_ptrを作成する
(関数テンプレート)
アロケータを使用して割り当てられた新しいオブジェクトを管理するshared_ptrを作成する
(関数テンプレート)
オブジェクトが自身を参照する shared_ptr を作成できるようにする
(クラステンプレート)