std::shared_ptr<T>:: shared_ptr
|
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
を構築します。
|
以下の説明の目的において、ポインタ型
|
(C++17 以降) |
shared_ptr
を構築します。つまり空の
shared_ptr
です。
ptr
を管理対象オブジェクトへのポインタとして
shared_ptr
を構築する。
|
(3,4,6)
に対して、
|
(C++17まで) |
|
|
(C++17以降) |
T
が配列型でない場合;
delete
[
]
ptr
T
が配列型の場合
(C++17以降)
を使用します。
Y
は完全型でなければなりません。delete式は適切な形式であり、明確に定義された動作を持ち、例外を送出してはなりません。
このコンストラクタは、delete式が適切な形式でない場合、オーバーロード解決に参加しません。
(C++17以降)
|
|
(C++17まで) |
|
これらのコンストラクタは、式 d ( ptr ) が適切に形成されていない場合、または std:: is_move_constructible_v < D > が false の場合、オーバーロード解決に参加しません。 |
(C++17以降) |
shared_ptr
を構築する。この
shared_ptr
がグループ内で最後にスコープ外になる場合、
r
が元々管理していたオブジェクトに対して保存されたデリータを呼び出す。ただし、この
shared_ptr
で
get()
を呼び出すと、常に
ptr
のコピーが返される。プログラマは、この
ptr
がこのshared_ptrが存在する限り有効であり続けることを保証する責任がある。例えば典型的な使用例では、
ptr
が
r
によって管理されるオブジェクトのメンバであるか、
r.get()
のエイリアス(例:ダウンキャスト)である場合など。
rvalueを受け取る2番目のオーバーロードでは、
r
は空となり、呼び出し後は
r.
get
(
)
==
nullptr
となる。
(C++20以降)
shared_ptr
を構築する。
r
がオブジェクトを管理していない場合、
*
this
もオブジェクトを管理しない。テンプレートオーバーロードは、
Y*
が
暗黙的に変換可能でない場合
(C++17まで)
互換性がない場合
(C++17以降)
、オーバーロード解決に参加しない。
r
から
shared_ptr
をムーブ構築する。構築後、
*
this
は
r
の以前の状態のコピーを含み、
r
は空となり、その格納されたポインタはnullとなる。このテンプレートオーバーロードは、
Y*
が
T*
に
暗黙的に変換可能でない場合
(C++17まで)
互換性がない場合
(C++17以降)
はオーバーロード解決に参加しない。
shared_ptr
を構築する。
Y*
は
T*
に暗黙的に変換可能でなければならない。
(C++17まで)
このオーバーロードは、
Y*
が
T*
と互換性がある場合にのみオーバーロード解決に参加する。
(C++17以降)
同じ目的には
r.
lock
(
)
が使用できることに注意:違いは、このコンストラクタは引数が空の場合に例外をスローするが、
std::
weak_ptr
<
T
>
::
lock
(
)
はその場合に空の
std::shared_ptr
を構築することである。
shared_ptr
を構築する。
Y*
は
T*
に変換可能でなければならない。構築後、
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
(
)
によって返されるポインタで有効にします。
目次 |
パラメータ
| ptr | - | 管理対象オブジェクトへのポインタ |
| d | - | オブジェクト破棄に使用するデリーター |
| alloc | - | 内部使用データの割り当てに使用するアロケーター |
| r | - | 所有権を共有または取得する別のスマートポインタ |
事後条件
HTMLタグ、属性、および`
`タグ内のC++コード(`use_count()`、`get()`、`ptr`)は翻訳せず、元のフォーマットを保持しました。技術文書として正確で専門的な日本語訳を心がけました。
例外
T
が配列型でない場合は
delete
[
]
ptr
が呼び出される
(C++17以降)
。
注記
コンストラクタは
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));
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を作成する
(関数テンプレート) |
|
|
(C++11)
|
オブジェクトが自身を参照する
shared_ptr
を作成できるようにする
(クラステンプレート) |