更新 : 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