weak_ptr
クラス
関連付けの弱いポインターをラップします。
構文
template<class T> class weak_ptr;
パラメーター
T
ウィーク ポインターによって制御される型。
解説
クラス テンプレートは、1 つ以上の shared_ptr
オブジェクトによって管理されるリソースを指すオブジェクトを記述します。 リソースを指し示す weak_ptr
オブジェクトは、そのリソースの参照カウントに一切影響を与えません。 リソースを管理する最後の shared_ptr
オブジェクトが破棄されると、仮にそのリソースを指し示す weak_ptr
オブジェクトが存在していたとしても、そのリソースは解放されます。 この動作は、データ構造の循環を防ぐうえで不可欠です。
weak_ptr
オブジェクトは、リソースを所有する shared_ptr
オブジェクトから構築された場合や、リソースを指し示す weak_ptr
オブジェクトから構築された場合、またはリソースが operator=
を使って割り当てられた場合に、そのリソースを指し示します。 weak_ptr
オブジェクトは、そのオブジェクトが指し示すリソースへの直接アクセスを提供しません。 そのリソースを使用する必要があるコードは、メンバー関数 lock
を呼び出すことによって作成された、そのリソースを所有する shared_ptr
オブジェクトを介してそのリソースを使用します。 weak_ptr
オブジェクトは、そのオブジェクトが指し示すリソースが解放されると、そのリソースを所有するすべての shared_ptr
オブジェクトが破棄されるため、期限切れになります。 有効期限の切れた weak_ptr
オブジェクトで lock
を呼び出すと、空の shared_ptr
オブジェクトが作成されます。
空の weak_ptr
オブジェクトは、リソースを一切参照せず、コントロール ブロックも持ちません。 そのメンバー関数 lock
は、空の shared_ptr
オブジェクトを返します。
循環は、shared_ptr
オブジェクトによって制御される複数のリソースで、相互に参照し合う shared_ptr
オブジェクトが保持されているときに発生します。 たとえば、3 つの要素から成るリンク リストがあるとします。先頭のノード N0
が 2 番目のノード N1
を所有する shared_ptr
オブジェクトを保持し、2 番目のノードが 3 番目のノード N2
を所有する shared_ptr
オブジェクトを保持し、次に、3 番目のノードが先頭のノード N0
を所有する shared_ptr
オブジェクトを保持しているとすると、ループが閉じた状態になり、このリストは循環リンク リストになります。 この状況では、参照カウントが 0 になることは決してなく、サイクル内のノードが解放されることはありません。 この循環を解消するためには、最後のノード N2
が、shared_ptr
オブジェクトではなく、N0
を指し示す weak_ptr
オブジェクトを保持する必要があります。 weak_ptr
オブジェクトは N0
を所有しないので、N0
の参照カウントに影響しません。先頭ノードに対するプログラムの最後の参照が破棄された時点で、リスト内のノードも破棄されます。
メンバー
名前 | 説明 |
---|---|
コンストラクター | |
weak_ptr |
weak_ptr を構築します。 |
デストラクター | |
~weak_ptr |
weak_ptr を破棄します。 |
Typedefs | |
element_type |
要素の型。 |
メンバー関数 | |
expired |
所有権の有効期限が切れているかどうかをテストします。 |
lock |
リソースの排他的所有権を取得します。 |
owner_before |
この weak_ptr が、指定されたポインターの前 (より小さい) に順序付けされている場合は true を返します。 |
reset |
所有されたリソースを解放します。 |
swap |
2 つの weak_ptr オブジェクトを交換します。 |
use_count |
shared_ptr オブジェクトの数をカウントします。 |
演算子 | |
operator= |
所有されたリソースを置換します。 |
element_type
要素の型。
typedef T element_type; // through C++17
using element_type = remove_extent_t<T>; // C++20
解説
この型は、テンプレート パラメーター T
のシノニムです。
例
// std__memory__weak_ptr_element_type.cpp
// compile with: /EHsc
#include <memory>
#include <iostream>
int main()
{
std::shared_ptr<int> sp0(new int(5));
std::weak_ptr<int> wp0(sp0);
std::weak_ptr<int>::element_type val = *wp0.lock();
std::cout << "*wp0.lock() == " << val << std::endl;
return (0);
}
*wp0.lock() == 5
expired
所有権の有効期限が切れているか、つまり参照先のオブジェクトが削除されたかテストします。
bool expired() const noexcept;
解説
メンバー関数は *this
の期限が切れた場合に true
を返し、それ以外の場合は false
を返します。
例
// std__memory__weak_ptr_expired.cpp
// compile with: /EHsc
#include <memory>
#include <iostream>
int main()
{
std::weak_ptr<int> wp;
{
std::shared_ptr<int> sp(new int(10));
wp = sp;
std::cout << "wp.expired() == " << std::boolalpha
<< wp.expired() << std::endl;
std::cout << "*wp.lock() == " << *wp.lock() << std::endl;
}
// check expired after sp is destroyed
std::cout << "wp.expired() == " << std::boolalpha
<< wp.expired() << std::endl;
std::cout << "(bool)wp.lock() == " << std::boolalpha
<< (bool)wp.lock() << std::endl;
return (0);
}
wp.expired() == false
*wp.lock() == 10
wp.expired() == true
(bool)wp.lock() == false
lock
リソースの所有権を共有する shared_ptr
を取得します。
shared_ptr<T> lock() const noexcept;
解説
このメンバー関数は、*this
が期限切れの場合、空の shared_ptr
オブジェクトを返します。それ以外の場合は、*this
が指し示すリソースを所有する shared_ptr<T>
オブジェクトを返します。 expired() ? shared_ptr<T>() : shared_ptr<T>(*this)
のアトミック実行に相当する値を返します。
例
// std__memory__weak_ptr_lock.cpp
// compile with: /EHsc
#include <memory>
#include <iostream>
int main()
{
std::weak_ptr<int> wp;
{
std::shared_ptr<int> sp(new int(10));
wp = sp;
std::cout << "wp.expired() == " << std::boolalpha
<< wp.expired() << std::endl;
std::cout << "*wp.lock() == " << *wp.lock() << std::endl;
}
// check expired after sp is destroyed
std::cout << "wp.expired() == " << std::boolalpha
<< wp.expired() << std::endl;
std::cout << "(bool)wp.lock() == " << std::boolalpha
<< (bool)wp.lock() << std::endl;
return (0);
}
wp.expired() == false
*wp.lock() == 10
wp.expired() == true
(bool)wp.lock() == false
operator=
所有されたリソースを置換します。
weak_ptr& operator=(const weak_ptr& ptr) noexcept;
template <class Other>
weak_ptr& operator=(const weak_ptr<Other>& ptr) noexcept;
template <class Other>
weak_ptr& operator=(const shared_ptr<Other>& ptr) noexcept;
パラメーター
Other
引数の共有ポインターまたはウィーク ポインターによって制御される型。
ptr
コピーする弱いポインターまたは共有ポインター。
解説
すべての演算子は、現在 *this
によって指し示されているリソースを解放し、ptr
で指定されたリソースの所有権を *this
に割り当てます。 演算子が失敗した場合、*this
は変更されません。 各演算子には、weak_ptr(ptr).swap(*this)
と同等の効果があります。
例
// std__memory__weak_ptr_operator_as.cpp
// compile with: /EHsc
#include <memory>
#include <iostream>
int main()
{
std::shared_ptr<int> sp0(new int(5));
std::weak_ptr<int> wp0(sp0);
std::cout << "*wp0.lock() == " << *wp0.lock() << std::endl;
std::shared_ptr<int> sp1(new int(10));
wp0 = sp1;
std::cout << "*wp0.lock() == " << *wp0.lock() << std::endl;
std::weak_ptr<int> wp1;
wp1 = wp0;
std::cout << "*wp1.lock() == " << *wp1.lock() << std::endl;
return (0);
}
*wp0.lock() == 5
*wp0.lock() == 10
*wp1.lock() == 10
owner_before
この weak_ptr
が、指定されたポインターの前 (より小さい) に順序付けされている場合は true
を返します。
template <class Other>
bool owner_before(const shared_ptr<Other>& ptr) const noexcept;
template <class Other>
bool owner_before(const weak_ptr<Other>& ptr) const noexcept;
パラメーター
ptr
shared_ptr
または weak_ptr
への lvalue
参照。
解説
テンプレート メンバー関数は、*this
が ptr
の前に並べられている場合、true
を返します。
reset
所有されたリソースを解放します。
void reset() noexcept;
解説
このメンバー関数は *this
によって指し示されるリソースを解放し、*this
を空の weak_ptr
オブジェクトに変換します。
例
// std__memory__weak_ptr_reset.cpp
// compile with: /EHsc
#include <memory>
#include <iostream>
int main()
{
std::shared_ptr<int> sp(new int(5));
std::weak_ptr<int> wp(sp);
std::cout << "*wp.lock() == " << *wp.lock() << std::endl;
std::cout << "wp.expired() == " << std::boolalpha
<< wp.expired() << std::endl;
wp.reset();
std::cout << "wp.expired() == " << std::boolalpha
<< wp.expired() << std::endl;
return (0);
}
*wp.lock() == 5
wp.expired() == false
wp.expired() == true
swap
2 つの weak_ptr
オブジェクトを交換します。
void swap(weak_ptr& wp) noexcept;
また、次の特殊化も含まれます。
template<class T>
void swap(weak_ptr<T>& a, weak_ptr<T>& b) noexcept;
パラメーター
wp
交換するウィーク ポインター。
解説
swap
の後、*this
による元のポイント先リソースは、wp
によってポイントされ、wp
による元のポイント先リソースは、*this
よってポイントされます。 この関数はこれら 2 つのリソースの参照数を変更せず、例外をスローしません。 テンプレートの特殊化の効果は、a.swap(b)
に相当します。
例
// std__memory__weak_ptr_swap.cpp
// compile with: /EHsc
#include <memory>
#include <iostream>
int main()
{
std::shared_ptr<int> sp1(new int(5));
std::shared_ptr<int> sp2(new int(10));
std::cout << "*sp1 == " << *sp1 << std::endl;
sp1.swap(sp2);
std::cout << "*sp1 == " << *sp1 << std::endl;
swap(sp1, sp2);
std::cout << "*sp1 == " << *sp1 << std::endl;
std::cout << std::endl;
std::weak_ptr<int> wp1(sp1);
std::weak_ptr<int> wp2(sp2);
std::cout << "*wp1 == " << *wp1.lock() << std::endl;
wp1.swap(wp2);
std::cout << "*wp1 == " << *wp1.lock() << std::endl;
swap(wp1, wp2);
std::cout << "*wp1 == " << *wp1.lock() << std::endl;
return (0);
}
*sp1 == 5
*sp1 == 10
*sp1 == 5
*wp1 == 5
*wp1 == 10
*wp1 == 5
use_count
共有リソースを所有する shared_ptr
オブジェクトの数をカウントします。
long use_count() const noexcept;
解説
このメンバー関数は、*this
が指し示すリソースを所有する shared_ptr
オブジェクトの数を返します。
例
// std__memory__weak_ptr_use_count.cpp
// compile with: /EHsc
#include <memory>
#include <iostream>
int main()
{
std::shared_ptr<int> sp1(new int(5));
std::weak_ptr<int> wp(sp1);
std::cout << "wp.use_count() == "
<< wp.use_count() << std::endl;
std::shared_ptr<int> sp2(sp1);
std::cout << "wp.use_count() == "
<< wp.use_count() << std::endl;
return (0);
}
wp.use_count() == 1
wp.use_count() == 2
weak_ptr
weak_ptr
を構築します。
constexpr weak_ptr() noexcept;
weak_ptr(const weak_ptr& wp) noexcept;
weak_ptr(weak_ptr&& wp) noexcept;
template <class Other>
weak_ptr(const weak_ptr<Other>& wp) noexcept;
template <class Other>
weak_ptr(weak_ptr<Other>&& sp) noexcept;
template <class Other>
weak_ptr(const shared_ptr<Other>& sp) noexcept;
パラメーター
Other
引数の共有ポインターまたはウィーク ポインターによって制御される型。 Other*
が element_type*
と互換性がない限り、これらのコンストラクターはオーバーロードの解決に関与しません。
wp
コピーするウィーク ポインター。
sp
コピーする共有ポインター。
解説
デフォルトのコンストラクターは、空の weak_ptr
オブジェクトを構築します。 引数ポインターが空の場合、引数を受け取るコンストラクターはそれぞれ、空の weak_ptr
オブジェクトを構築します。 それ以外の場合は、引数で指定されたリソースを指す weak_ptr
オブジェクトを構築します。 共有オブジェクトの参照カウントは変更されません。
例
// std__memory__weak_ptr_construct.cpp
// compile with: /EHsc
#include <memory>
#include <iostream>
int main()
{
std::weak_ptr<int> wp0;
std::cout << "wp0.expired() == " << std::boolalpha
<< wp0.expired() << std::endl;
std::shared_ptr<int> sp1(new int(5));
std::weak_ptr<int> wp1(sp1);
std::cout << "*wp1.lock() == "
<< *wp1.lock() << std::endl;
std::weak_ptr<int> wp2(wp1);
std::cout << "*wp2.lock() == "
<< *wp2.lock() << std::endl;
return (0);
}
wp0.expired() == true
*wp1.lock() == 5
*wp2.lock() == 5
~weak_ptr
weak_ptr
を破棄します。
~weak_ptr();
解説
デストラクターはこの weak_ptr
を破棄しますが、格納されているポインターが指すオブジェクトの参照カウントには影響しません。