SharedPtr

SharedPtr<T>

nine は、SharedPtr< T > というテンプレートクラスを提供している。 これは、いわゆる参照カウント式のスマートポインタである。

通常のポインタと同様に扱え、全ての参照が無くなった時にポインタの解放が行われる。

Sharable

SharedPtr に与えるクラスは Sharable を継承しなければならない。

Sharable の定義は以下のようになっている:
class Sharable
{
   protected:
      inline virtual ~Sharable() { }
      virtual void finalize() = 0;

解放時に finalize() 関数が呼ばれ、その後に delete される。 ユーザーは finalize() かデストラクタに後始末処理を記述することができる。

SharedPtr の使い方

自前で使うには、Sharable を継承したクラスを作らなければならない。 finalize() 関数が必須である。:
  class Foo: public Sharable {
    public:
      inline virtual void finalize() { printf("fin\n"); } //破壊時に呼ばれる
      inline void dump() { printf("foo\n"); }
  };
  typedef SharedPtr< Foo > FooPtr;
上のコードのように、typedef しておくと便利。
SharedPtr を使う場合は、SharedPtr インスタンスの新規生成を行う。 通常はスタックに確保する。
FooPtr pf;
ヒープに確保することもできるが、それでは SharedPtr を使う利点が無い。
デフォルトコンストラクタでは、SharedPtr の指すポイントは NULL である。 実際の Sharable ポインタを渡すには、代入オペレータやコンストラクタを用いる:
FooPtr pf(new Foo());
pf = new Foo();
ポインタへアクセスするには operator-> を用いる:
pf->dump();
記述法は通常のポインタと同じになっている。
上では生の T* ポインタを代入したが、SharedPtr を渡すこともできる。
FooPtr pf2;
pf2 = pf;
SharedPtr 同士の比較は、内部ポインタに対して行われる:
if (pf == pf2) { ; } // true
生の T* ポインタ及び NULL に対する比較も可能である:
if (pf == NULL) { ; }
特に、デフォルトコンストラクタで生成した直後は NULL との比較は真である。
ある T* を参照する最後の SharedPtr が消えた時に、その T* は解放される:
  void foo() {
    FooPtr pf,pf2;
    pf = new Foo();
    pf2 = pf;
    pf = NULL;
  }
関数から出る時にスタック上にある pf,pf2 は解放される。 両方が消える時に、new Foo() でヒープ上に生成した Foo インスタンスの解放も行われる。