std::weak_ptr
ヘッダ <memory> で定義 | ||
template<class T >class weak_ptr; | (C++11以上) | |
std::weak_ptr
は std::shared_ptr によって管理されているオブジェクトへの所有していない (「弱い」) 参照を保持するスマートポインタです。 参照先のオブジェクトにアクセスするためには std::shared_ptr に変換しなければなりません。
std::weak_ptr は一時的な所有権をモデル化します。 オブジェクトが存在する場合にのみそのオブジェクトへのアクセスを必要とし、他の誰かによっていつでも削除されて構わない場合、そのオブジェクトを追跡するために std::weak_ptr が使用され、一時的に所有権を得るために std::shared_ptr に変換されます。 このとき元の std::shared_ptr が破棄された場合でも、一時的な std::shared_ptr が同様に破棄されるまで、そのオブジェクトの生存期間は延長されます。
std::weak_ptr のもうひとつの用途は、 std::shared_ptr によって形成される循環参照を断ち切ることです。 そのような循環が孤立している (すなわち、その循環を指す外側の shared_ptr がない) 場合、 shared_ptr の参照カウントはゼロに達せず、メモリはリークします。 これを防ぐために、循環内のポインタのいずれかを weak にすることができます。
目次 |
[編集]メンバ型
メンバ型 | 定義 | ||||
element_type |
|
[編集]メンバ関数
新しい weak_ptr を作成します (パブリックメンバ関数) | |
weak_ptr を破棄します (パブリックメンバ関数) | |
weak_ptr を代入します (パブリックメンバ関数) | |
変更 | |
管理対象オブジェクトの所有権を解放します (パブリックメンバ関数) | |
管理対象オブジェクトを入れ替えます (パブリックメンバ関数) | |
観察 | |
オブジェクトを管理している shared_ptr オブジェクトの数を返します (パブリックメンバ関数) | |
参照先のオブジェクトがすでに削除されたか調べます (パブリックメンバ関数) | |
参照先のオブジェクトを管理する shared_ptr を作成します (パブリックメンバ関数) | |
weak_ptr のオーナーベースの順序付けを提供します (パブリックメンバ関数) |
[編集]非メンバ関数
(C++11) | std::swap アルゴリズムの特殊化 (関数テンプレート) |
[編集]ヘルパークラス
(C++20) | アトミックなウィークポインタ (クラステンプレートの特殊化) |
[編集]推定ガイド(C++17以上)
[編集] ノート
std::shared_ptr と同様に、一般的な weak_ptr
の実装は2つのポインタを格納します。
- 制御ブロックへのポインタ
- 構築元の
shared_ptr
が格納していたポインタ
別に格納されているポインタは、エイリアスされた shared_ptr
に対しても、 shared_ptr
を weak_ptr
へ変換し、その後元に戻したときに正しく戻ることを保証するために、必要です。 shared_ptr
へロックせずに weak_ptr
に格納されているポインタへアクセスすることはできません。
[編集] 欠陥報告
以下の動作変更欠陥報告は以前に発行された C++ 標準に遡って適用されました。
DR | 適用先 | 発行時の動作 | 正しい動作 |
---|---|---|---|
LWG 3001 | C++17 | element_type was not updated for array support | updated |
[編集]例
ポインタの有効性を保証するためにロックをどのように使用するかをデモンストレーションします。
#include <iostream>#include <memory> std::weak_ptr<int> gw; void observe(){std::cout<<"use_count == "<< gw.use_count()<<": ";if(auto spt = gw.lock()){// Has to be copied into a shared_ptr before usagestd::cout<<*spt <<"\n";}else{std::cout<<"gw is expired\n";}} int main(){{auto sp =std::make_shared<int>(42); gw = sp; observe();} observe();}
出力:
use_count == 1: 42 use_count == 0: gw is expired