# weak_ptr class template

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

全てのweak_ptrはC++標準ライブラリのCopyConstructibleと Assignableの要求を満たしているので標準ライブラリコンテナで使うことができる。 比較演算子が提供されているので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
    }

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

## Synopsis

    namespace boost {

      template<typename T> class weak_ptr {

        public:
          typedef T element_type;

          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.