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 参照。

解説

テンプレート メンバー関数は、*thisptr の前に並べられている場合、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 を破棄しますが、格納されているポインターが指すオブジェクトの参照カウントには影響しません。

関連項目

ヘッダー ファイル リファレンス
<memory>
shared_ptr クラス