最終更新日時:
が更新

履歴 編集

weak_ptr class template

weak_ptrクラステンプレートはshared_ptrがすでに管理しているオブジェクトへの「弱参照」を所有する。 オブジェクトにアクセスするにweak_ptrは、shared_ptr constructormake_shared関数によって、shared_ptrに変換することができる。 最後のshared_ptrが廃棄され、オブジェクトが削除されたら、削除されたオブジェクトを参照するweak_ptrの実体からshared_ptrを得ようとすると失敗するだろう。 コンストラクタはboost::use_const_is_zero型の例外を投げ、make_shared関数はデフォルトのコンストラクタで構築された(nullの)shared_ptrを返す。

全てのweak_ptrはC++標準ライブラリのCopyConstructibleAssignableの要求を満たしているので標準ライブラリコンテナで使うことができる。 比較演算子が提供されているのでweak_ptrは標準関数の連想コンテナで使うことができる。

クラステンプレートはテンプレートパラメータTをもつ。 これは指されるオブジェクトの型である。 Tはスマートポインタのcommon requirementsを満たしていなければならない。

shared_ptrに比べて、weak_ptrは限られたサブセットの操作しか提供しない。 これは、マルチスレッドプログラムで、所有するポインタにアクセスすることはたいてい危険であり、また時々、シングルスレッドプログラムの中でも安全ではないからである。 (つまり未定義の動作を引き起こしてしまうのだ。) 例えば、次のような不完全なプログラムの一部を考えてみよう:

shared_ptr<int> p(new int(5));
weak_ptr<int> q(p);

// some time later

if(int * r = q.get())
{
// use *r
}

ifのあと、rが使われる直前に別のスレッドがp.reset()ステートメントを実行することを考えてみよう。 今、rはダングリングポインタである。 (※訳注:ダングリングポインタ(dangling pointer)とは何をさしているか分からないポインタのこと)

この問題を解決する方法は、qから一時的なshared_ptrを作ることである。

shared_ptr<int> p(new int(5));
weak_ptr<int> q(p);

// some time later

if(shared_ptr<int> r = make_shared(q))
{
// use *r
}

ここではrqが指すポインタへの参照を持っている。 もしp.reset()が別のスレッドで実行されても、オブジェクトはrがスコープの外に出てしまう(或いはresetされてしまう)まで生きたままである。

Synopsis

namespace boost {

template<typename T> class weak_ptr {

public:
    typedef T <a href="#element_type">element_type</a>;

    weak_ptr();
    template<typename Y>
    weak_ptr(shared_ptr<Y> const & r); // never throws
    ~weak_ptr(); // never throws

    weak_ptr(weak_ptr const & r); // never throws
    template<typename Y>
    weak_ptr(weak_ptr<Y> const & r); // never throws

    weak_ptr & operator=(weak_ptr const & r); // never throws  
    template<typename Y>
    weak_ptr & operator=(weak_ptr<Y> const & r); // never throws
    template<typename Y>
    weak_ptr & operator=(shared_ptr<Y> const & r); // never throws

    void reset();
    T * get() const; // never throws; deprecated, will disappear

    long use_count() const; // never throws
    bool expired() const; // never throws

    void swap(weak_ptr<T> & b); // never throws
};

template<typename T, typename U>
bool operator==(weak_ptr<T> const & a, weak_ptr<U> const & b); // never throws
template<typename T, typename U>
bool operator!=(weak_ptr<T> const & a, weak_ptr<U> const & b); // never throws
template<typename T>
bool operator<(weak_ptr<T> const & a, weak_ptr<T> const & b); // never throws

template<typename T>
void swap(weak_ptr<T> & a, weak_ptr<T> & b); // never throws

template<typename T>
shared_ptr<T> make_shared(weak_ptr<T> const & r); // never throws

}

Members

element_type

typedef T element_type;

テンプレートパラメータの型Tを与える

constructors

weak_ptr();

  • Effects:
    • weak_ptrをコンストラクトする。
  • Postconditions:
    • use countは0。 所有するポインタは0。
  • Throws:
    • std::bad_alloc.
  • Exception safety:
    • 例外が投げられると、コンストラクタは何もしない。
  • Notes:
    • Tは完全な型である必要はない。 スマートポインタのcommon requirementsを参考にせよ。

template<typename Y>
weak_ptr(shared_ptr<Y> const & r); // never throws

  • Effects:
    • weak_ptrをコンストラクトし、rが所有するポインタのコピーを持つ。
  • Throws:
    • なし。
  • Notes:
    • 全てのコピーに対してuse countは変更されない。 最後のshared_ptrが破棄されるとき、use countと所有するポインタは0になる。

weak_ptr(weak_ptr const & r); // never throws
template<typename Y>
weak_ptr(weak_ptr<Y> const & r); // never throws

  • Effects:
    • weak_ptrをコンストラクトし、rが所有するポインタのコピーを持つ。
  • Throws:
    • なし.
  • Notes:
    • 全てのコピーに対してuse countは変更されない。

destructor

~weak_ptr(); // never throws

  • Effects:
    • このweak_ptrを破棄するが、所有するポインタが指すオブジェクトには何も影響しない。
  • Throws:
    • なし.
  • Notes:
    • Tは完全な型である必要はない。 スマートポインタのcommon requirementsを参考にせよ。

assignment

weak_ptr & operator=(weak_ptr const & r); // never throws
template<typename Y>
weak_ptr & operator=(weak_ptr<Y> const & r); // never throws
template<typename Y>
weak_ptr & operator=(shared_ptr<Y> const & r); // never throws

  • Effects:
    • weak_ptr(r).swap(*this)と等価.
  • Throws:
    • なし.
  • Notes:
    • 効果(と保証)を満たす限り実装は自由である。 一時的オブジェクトが作られることはない。

reset

void reset();

  • Effects:
    • weak_ptr().swap(*this)と等価.

get

T * get() const; // never throws

  • Returns:
    • 所有するポインタ(そのポインタのための全てのshared_ptrオブジェクトが破棄されていれば0)
  • Throws:
    • なし.
  • Notes:
    • マルチスレッドのコードでgetを使うのは危険である。 関数から戻った後、指しているオブジェクトを別のスレッドが破棄してしまうかもしれない。 weak_ptrはそのuse_countを変更しないからである。

[getは非常にエラーを起こしやすい。 シングルスレッドのコードでも、例えば指されたオブジェクトのメンバ関数によって間接的に、getが返すポインタが無効にされているかもしれない。

getは非難されているし、将来のリリースでは無くなるだろう。 決してこれを使わないこと。]

use_count

long use_count() const; // never throws

  • Returns:
    • 所有するポインタを共有するshared_ptrオブジェクトの数
  • Throws:
    • なし.
  • Notes:
    • use_count()は必ずしも効率的ではない。 デバッグとテストの目的でのみ使い、製品コードでは使わないこと。 Tは完全な型である必要はない。 スマートポインタのcommon requirementsを参考にせよ。

expired

bool expired() const; // never throws

  • Returns:
    • use_count() == 0.
  • Throws:
    • なし.
  • Notes:
    • expired()use_count()より速いかもしれない。 Tは完全な型である必要はない。 スマートポインタのcommon requirementsを参考にせよ。

swap

void swap(weak_ptr & b); // never throws

  • Effects:
    • ふたつのポインタの内容を入れ替える。
  • Throws:
    • なし.
  • Notes:
    • Tは完全な型である必要はない。 スマートポインタのcommon requirementsを参考にせよ。

Free Functions

comparison

template<typename T, typename U>
bool operator==(weak_ptr<T> const & a, weak_ptr<U> const & b); // never throws
template<typename T, typename U>
bool operator!=(weak_ptr<T> const & a, weak_ptr<U> const & b); // never throws

  • Returns:
    • a.get() == b.get().
  • Throws:
    • なし.
  • Notes:
    • Tは完全な型である必要はない。 スマートポインタのcommon requirementsを参考にせよ。

template<typename T>
bool operator<(weak_ptr<T> const & a, weak_ptr<T> const & b); // never throws

  • Returns:
    • an implementation-defined value such that operator< is a strict weak ordering as described in section 25.3 [lib.alg.sorting] of the C++ standard.
  • Throws:
    • なし.
  • Notes:
    • weak_ptrオブジェクトが連想コンテナのキーとして使われることを許す。 Tは完全な型である必要はない。 スマートポインタのcommon requirementsを参考にせよ。

swap

template<typename T>
void swap(weak_ptr<T> & a, weak_ptr<T> & b) // never throws

  • Effects:
    • a.swap(b)と等価.
  • Throws:
    • なし.
  • Notes:
    • std::swapインタフェースと同じ。 ジェネリックプログラミングを助けるだろう。

make_shared

template<typename T>
shared_ptr<T> make_shared(weak_ptr<T> & const r) // never throws

  • Returns:
    • r.expired()? shared_ptr<T>(): shared_ptr<T>(r).
  • Throws:
    • なし.

[make_sharedの現在の実装はshared_ptrのデフォルトコンストラクタでの例外を転送することができるので、明示された要求を満たしていない。 将来のリリースではこのデフォルトコンストラクタは例外を投げないだろう。]


Revised 29 August 2002

Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler. Copyright 2002 Peter Dimov. Permission to copy, use, modify, sell and distribute this document is granted provided this copyright notice appears in all copies. This document is provided "as is" without express or implied warranty, and with no claim as to its suitability for any purpose.