次の方法で共有


shared_ptr クラス

更新 : 2007 年 11 月

共有可能なポインタをラップします。

template<class Ty>
   class shared_ptr {
public:
   typedef Ty element_type;

   shared_ptr();
   template<class Other>
      explicit shared_ptr(Other*);
   template<class Other, class D>
      shared_ptr(Other*, D);
      template<class Other, class D, class A>
      shared_ptr(Other *ptr, D dtor, A ator);
   shared_ptr(const shared_ptr&);
   template<class Other>
      shared_ptr(const shared_ptr<Other>&);
   template<class Other>
      shared_ptr(const weak_ptr<Other>&);
   template<class &>
      shared_ptr(const std::auto_ptr<Other>&);
   ~shared_ptr();

   shared_ptr& operator=(const shared_ptr&);
   template<class Other>
      shared_ptr& operator=(const shared_ptr<Other>&);
   template<class Other>
      shared_ptr& operator=(auto_ptr<Other>&);

   void swap(shared_ptr&);
   void reset();
   template<class Other>
      void reset(Other*);
   template<class Other, class D>
      void reset(Other*, D);

   Ty *get() const;
   Ty& operator*() const;
   Ty *operator->() const;
   long use_count() const;
   bool unique() const;
   operator boolean-type() const;
   };

パラメータ

  • Ty
    共有ポインタによって制御される型。

解説

このテンプレート クラスは、参照カウントを使ってリソースを管理するオブジェクトを表します。各 shared_ptr オブジェクトは、所有しているリソースへのポインタまたは null ポインタを効率的に保持します。複数の shared_ptr オブジェクトが 1 つのリソースを所有することも可能です。その場合、特定のリソースを所有する最後の shared_ptr オブジェクトは、リソースが解放された時点で破棄されます。

テンプレートの引数 Ty は、特定のオペランド シーケンスについて注記がある場合を除き、不完全な型になる場合があります。

shared_ptr<Ty> オブジェクトを D* 型のリソース ポインタまたは shared_ptr<D> から構築する場合、ポインタの型 D* は Ty* に変換可能であることが必要です。この条件が満たされていない場合、コードはコンパイルされません。次に例を示します。

class B {};
class D : public B {};

shared_ptr<D> sp0(new D);   // okay, template parameter D and argument D*
shared_ptr<D> sp1(sp0);     // okay, template parameter D and argument shared_ptr<D>
shared_ptr<B> sp2(new D);   // okay, D* convertible to B*
shared_ptr<B> sp3(sp0);     // okay, template parameter B and argument shared_ptr<D>
shared_ptr<B> sp4(sp2);     // okay, template parameter B and argument shared_ptr<B>
shared_ptr<int> sp4(new D); // error, D* not convertible to int*
shared_ptr<int> sp5(sp2);   // error, template parameter int and argument shared_ptr<B>

shared_ptr オブジェクトがリソースを所有するためには、次のいずれかの条件を満たしている必要があります。

そのリソースへのポインタを使って構築されている。

そのリソースを所有する shared_ptr オブジェクトから構築されている。

そのリソースを指し示す weak_ptr クラス オブジェクトから構築されている。

そのリソースの所有権が、shared_ptr::operator= またはメンバ関数 shared_ptr::reset の呼び出しのいずれかによって割り当てられている。

単一のリソースを所有するすべての shared_ptr オブジェクトは、リソースを所有する shared_ptr オブジェクトの数、リソースを指し示す weak_ptr オブジェクトの数、および (存在する場合は) リソースの削除子を保持するコントロール ブロックを共有します。null ポインタで初期化された shared_ptr オブジェクトにはコントロール ブロックが存在するので、この shared_ptr オブジェクトは空ではありません。shared_ptr オブジェクトがリソースを所有するのは、そのリソースが解放されるまでの間です。weak_ptr オブジェクトがリソースを指し示すのは、そのリソースが解放されるまでの間です。リソースを所有する shared_ptr オブジェクトの数がゼロになると、リソースを削除するか、リソースのアドレスを削除子に渡すことによって、リソースが解放されます。どちらの方法で解放されるかは、最初にリソースの所有権が作成された方法によって決定されます。リソースを所有する shared_ptr オブジェクトの数がゼロになり、なおかつ、リソースを指し示す weak_ptr オブジェクトの数がゼロになると、コントロール ブロックが解放されます。

空の shared_ptr オブジェクトは、リソースを一切所有せず、コントロール ブロックも持ちません。

削除子とは、メンバ関数 operator() を持つ型のオブジェクトまたは関数ポインタです。この型はコピーによって構築可能であること、また、コピー コンストラクタおよびデストラクタによって例外がスローされないことが必要です。削除子は、ptr, dtor 形式のオペランド シーケンスで shared_ptr オブジェクトにバインドされます。

一部の関数では、結果として生成される shared_ptr<Ty> または weak_ptr<Ty> オブジェクトのプロパティを定義するオペランド シーケンスが使用されます。その場合、オペランド シーケンスは次のような方法で指定できます。

引数なし : 結果として生成されるオブジェクトは、空の shared_ptr オブジェクトまたは空の weak_ptr オブジェクトです。

ptr: 管理対象リソースに対する Other* 型のポインタです。Ty は完全な型である必要があります。関数が失敗した場合、delete ptr という式が評価されます。

ptr, dtor: 管理対象リソースに対する Other* 型のポインタおよびそのリソースの削除子です。関数が失敗した場合、dtor(ptr) が呼び出されます (明確に定義されていることが必要)。

sp: 管理対象のリソースを所有する shared_ptr<Other> オブジェクトです。

wp: 管理対象のリソースを指し示す weak_ptr<Other> オブジェクトです。

ap: 管理対象のリソースへのポインタを保持する auto_ptr<Other> オブジェクトです。関数が成功した場合は、ap.release() が呼び出されます。関数が失敗した場合は、ap は変更されません。

いずれの場合も、ポインタの型 Other* は Ty* に変換可能である必要があります。

スレッド セーフ

複数のスレッドが異なる shared_ptr オブジェクト (所有権を共有するコピーである場合も含めて) に対する読み取りと書き込みを同時に行うことができます。

必要条件

ヘッダー : <memory>

名前空間 : std::tr1

参照

参照

<memory> (TR1)

weak_ptr クラス

Thread Safety in the Standard C++ Library