std::tr1::shared_ptr は、参照カウンタを用いた高機能なスマートポインタです。std::tr1::shared_ptr の詳細な仕様は、boost::shared_ptr を参照してください。ここでは、主な仕様をかいつまんで解説することにします。

namespace std {
  namespace tr1 {

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

      // コンストラクタ
      shared_ptr();
      template<class Y> explicit shared_ptr(Y* p);
      template<class Y, class D> shared_ptr(Y* p, D d);
      shared_ptr(shared_ptr const& r);
      template<class Y> shared_ptr(shared_ptr<Y> const& r);
      template<class Y> explicit shared_ptr(weak_ptr<Y> const& r);
      template<class Y> explicit shared_ptr(auto_ptr<Y>& r);

      // デストラクタ
      ~shared_ptr();

      // 代入演算子
      shared_ptr& operator=(shared_ptr const& r);
      template<class Y> shared_ptr& operator=(shared_ptr<Y> const& r);
      template<class Y> shared_ptr& operator=(auto_ptr<Y>& r);

      // 更新操作
      void swap(shared_ptr& r);
      void reset();
      template<class Y> void reset(Y* p);
      template<class Y, class D> void reset(Y* p, D d);

      // 参照操作
      T* get() const;
      T& operator*() const;
      T* operator->() const;
      long use_count() const;
      bool unique() const;
      operator unspecified-bool-type () const;
    };

    // 等価・関係演算子
    template<class T, class U>
      bool operator==(shared_ptr<T> const& a,  shared_ptr<U> const& b);
    template<class T, class U>
      bool operator!=(shared_ptr<T> const& a,   shared_ptr<U> const& b);
    template<class T, class U>
      bool operator<(shared_ptr<T> const& a, shared_ptr<U> const& b);

    // ストリームへの出力
    template<class E, class T, class Y>
    basic_ostream<E, T>& operator<< (basic_ostream<E, T>& os,
                                     shared_ptr<Y> const& p);

    // 値の交換
    template<class T> void swap(shared_ptr<T>& a, shared_ptr<T>& b);

    // 型変換
    template<class T, class U>
     shared_ptr<T> static_pointer_cast(shared_ptr<U> const& r);
    template<class T, class U>
     shared_ptr<T> dynamic_pointer_cast(shared_ptr<U> const& r);
    template<class T, class U>
     shared_ptr<T> const_pointer_cast(shared_ptr<U> const& r);

    // 解体子の参照
    template<class D, class T> D* get_deleter(shared_ptr<T> const& p);

  } // namespace tr1
} // namespace std

コンストラクタ

shared_ptr には多くのコンストラクタがあります。その中でも、特に重要なコンストラクタに絞って解説することにします。

template<class Y> explicit shared_ptr(Y* p);

この形式では、基本的には new で生成したオブジェクトへのポインタ p を渡すことになります。delete p が合法でなければならず、デストラクタが例外を送出してはなりません。すなわち、配列形式の new で生成した場合には、delete[] p としなければなりせんので、適合しないのです。Boost C++ Libraries には、配列用の shared_array がありますが、TR1 に shared_array はありません。

Y は型 T と互換でなければなりません。ここで注目すべきは、型 Y が型 T の派生クラスの場合、仮想デストラクタがなくても正しく動作するということです。なぜなら、仕様が要求しているのは、delete p が合法であることであって、delete (T*)p が合法であることではないからです。

このコンストラクタで例外が発生した場合、delete p を呼び出します。

template<class Y, class D> shared_ptr(Y* p, D d);

この形式では、delete p が合法であることは要求されません。代わりに、解体子 d を用いて、d(p) によって解放できなければなりません。適切な d を用意すれば、shared_ptr に配列形式の new で生成したオブジェクトへのポインタを渡すことも可能です。ただし、添え字演算などは用意されていませんので、必ずしも使い勝手のよいものとはなりません。また、malloc 関数で割り付けたオブジェクトへのポインタを渡し、第 2 引数に &std::free を渡すことも可能です。

このコンストラクタで例外が発生した場合、d(p) を呼び出します。

shared_ptr(shared_ptr const& r);
template<class Y> shared_ptr(shared_ptr<Y> const& r);

これらのコンストラクタは、スマートポインタのコピーを行うためのものです。すなわち、参照カウンタをインクリメントすることで、オブジェクトの参照元を新たに登録することになります。このコンストラクタが例外を送出することはありません。

TR1 の仕様では触れられていませんが、通常、スレッドセーフにするために、これらのコンストラクタは内部で排他制御が行われます。結果として、通常のポインタに比べて、shared_ptr のコピーは非常にコストが大きいものとなります。

デストラクタ

~shared_ptr();

デストラクタは次のように振舞います。

  • *this がオブジェクトを参照していなければ、何も行いません。
  • *this が他の shared_ptr とオブジェクトを共有している場合、すなわち、参照カウンタが 1 より大きい場合には、参照カウンタをデクリメントします。
  • そうではなく、参照先のオブジェクトへのポインタ p と解体子 d が設定されているなら、d(p) を実行します。
  • そうではなく、参照先のオブジェクトへのポインタ p が設定されているなら、delete p を実行します。

やはり TR1 では触れられていませんが、コピーの場合と同様、参照カウンタをデクリメントする場合には排他制御が行われます。

代入演算子

代入演算子は、それぞれ対応するコンストラクタと同等の振る舞いをします。

更新処理

void swap(shared_ptr& r);

内容の交換を行います。このメンバ関数が例外を送出することはありません。

void reset();
template<class Y> void reset(Y* p);
template<class Y, class D> void reset(Y* p, D d);

それぞれの引数に対応したコンストラクタによって構築した shared_ptr で再初期化します。

参照処理

shared_ptr の状態を参照するためのメンバ関数です。参照処理のためのメンバ関数が例外を送出することはありません。

T* get() const;

shared_ptr が保持している、参照先オブジェクトへのポインタを返します。

T& operator*() const;
T* operator->() const;
operator unspecified-bool-type () const;

ポインタと同様に振舞うために * および -> 演算子を定義するためのものです。unspecified-bool-type はブール値を表すための適当な型ですが、bool であるとは限りません。

long use_count() const;
bool unique() const;

use_count は、参照カウンタの値を返します。参照カウンタが 1 であれば、他に参照先のオブジェクトを共有している shared_ptr はありません。参照カウンタが 0 であれば、*this はどのオブジェクトも参照していません。

unique は、参照カウンタが 1 かどうかを判定します。

型変換

template<class T, class U>
  shared_ptr<T> static_pointer_cast(shared_ptr<U> const& r);
template<class T, class U>
  shared_ptr<T> dynamic_pointer_cast(shared_ptr<U> const& r);
template<class T, class U>
  shared_ptr<T> const_pointer_cast(shared_ptr<U> const& r);

xxx_cast<T*>(r,get()) として型変換を行います。xxx_cast の部分はそれぞれ、static_cast, dynamic_cast, const_cast になります。すなわち、static_pointer_cast であれば、内部で管理するポインタに対して static_cast を行うことになります。reinterpret_cast 相当のものはありません。