c++boost.gif (8819 bytes)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++標準ライブラリの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 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.

Japanese Translation Copyright (C) 2003 Ryo Kobayashi.
オリジナルの、及びこの著作権表示が全ての複製の中に現れる限り、この文書の 複製、利用、変更、販売そして配布を認める。このドキュメントは「あるがまま」 に提供されており、いかなる明示的、暗黙的保証も行わない。また、 いかなる目的に対しても、その利用が適していることを関知しない。