<注意!>
 以下は古い実装になりました。現在下記の実装についてサポートは終了しております。
最新の実装はツール編「スマートポインタ」をご覧下さい。


smart_ptrクラスの完全実装

 以下から下をコピペすると直ぐに使えるようになります。
 デバッグ時に「DEBUG_smp.txt」というテキストファイルを出力させるため#ifディレクティブなどが
ついております。見づらい点はご了承ください。


// smart_ptrクラス

// 動的に生成された変数の削除を管理し、実体への参照が無い時に消去する。
// smart_ptrクラスを通した実体への参照を保証する。


// デバッグ時には「DEBUG_smp.txt」というデバッグファイルを出力


template <class T>
class smart_ptr
{
private:
   UINT *m_pRefCnt;   // 参照カウンタへのポインタ
   T* m_pPtr;   // T型のオブジェクトのポインタ

private:
   // 参照カウンタ増加
#if _DEBUG
   void AddRef(char *coment="No Coment")
   {
      (*m_pRefCnt)++;
       // 出力
      ofstream ofs;
       ofs.open("DEBUG_smp.txt", ios::app);
       ofs << this << "\t" << m_pPtr << "\t[" << *m_pRefCnt << "]\t" << coment << endl;
       ofs.close();
   }
#else
   void AddRef(){(*m_pRefCnt)++;}
#endif

   // 参照カウンタを減少
#if _DEBUG
   void Release(char *coment="No Coment")
#else
   void Release()
#endif
   {
#ifdef _DEBUG
      ofstream ofs;
      ofs.open("DEBUG_smp.txt", ios::app);
      ofs << this << "\t" << m_pPtr << "\t[" << *m_pRefCnt-1 << "]\t" << coment << endl;
      ofs.close();
#endif
      if(--(*m_pRefCnt) == 0){
          delete[] m_pPtr;
          delete m_pRefCnt;
      }
   }

public:
   // デフォルトコンストラクタ
   explicit smart_ptr(T* src=NULL)
   {
      m_pRefCnt = new UINT;
      *m_pRefCnt = 0;
      m_pPtr = src;
      #if _DEBUG
         AddRef("デフォルトコンストラクタによりカウンタ増加");
      #else
         AddRef();
      #endif
   }

   // コピーコンストラクタ
   smart_ptr(const smart_ptr<T> &src)
   {
      // ポインタコピー
      m_pRefCnt = src.m_pRefCnt;
      m_pPtr = src.m_pPtr;

      // 自分自身の参照カウンタを増加
      #if _DEBUG
         AddRef("コピーコンストラクタによりカウンタ増加");
      #else
         AddRef();
      #endif
   }

   // デストラクタ
   virtual ~smart_ptr()
   {
      #if _DEBUG
         char c[100];
         sprintf(c, "デストラクタで%08xの参照カウンタを減少\0", m_pPtr);
         Release(c);
      #else
         Release();
      #endif
   }

   // =演算子のオーバーロード(明示的なコピー)
   smart_ptr& operator =(const smart_ptr<T> &src)
   {
      // 自分自身への代入は不正で意味が無いので
      // 行わない。
      if(src.m_pPtr == m_pPtr)
         return (*this);

      // 自分の参照カウンタを1つ減少
      #if _DEBUG
         char c[100];
         sprintf(c, "=演算子中で%08xの参照カウンタを減少\0", m_pPtr);
         Release(c);
      #else
         Release();
      #endif

      // ポインタコピー
      m_pRefCnt = src.m_pRefCnt;
      m_pPtr = src.m_pPtr;

      // 自分自身の参照カウンタを増加
      #if _DEBUG
         sprintf(c, "=演算子中で%08xの参照カウンタを増加\0", m_pPtr);
         AddRef(c);
      #else
         AddRef();
      #endif

      return (*this);
   }


// メンバ関数
   // ポインタを移譲
   void SetPtr(T* src = NULL)
   {
      // 参照カウンタを減らした後に再初期化
      #if _DEBUG
         char c[100];
         sprintf(c, "SetPtr関数中で%08xの参照カウンタを減少\0", m_pPtr);
         Release(c);
      #else
         Release();
      #endif
         m_pRefCnt = new UINT;
         *m_pRefCnt = 0;
         m_pPtr = src;

      #if _DEBUG
         sprintf(c, "SetPtr関数中で%08xの参照カウンタを増加\0", m_pPtr);
         AddRef(c);
      #else
         AddRef();
      #endif
   }


   // ポインタの貸し出し
   T* GetPtr(){return m_pPtr;}

   // 参照カウンタへのポインタを取得
   UINT* GetRefPtr(){return m_pRefCnt;}

   // アップキャスト
   // ChildPtrはsmart_ptr::GetPtr関数で得られるポインタでなければエラー
   // pRefCntはsmart_ptr::GetRefPtr関数で得られる参照カウンタへの
   //  ポインタでなければエラーになるので注意!
   void Upcast(T* ChildPtr, UINT* pRefCnt)
   {
      // 引数のポインタが同じ場合は意味が無いのでキャストしない
      if(ChildPtr == m_pPtr)
         return;

      // 引数のポインタと参照カウンタを受け継ぐ
      #if _DEBUG
         char c[100];
         sprintf(c, "Upcast関数中で%08xの参照カウンタを減少\0", m_pPtr);
         Release(c);
      #else
         Release();
      #endif

      // ポインタコピー
         m_pPtr = ChildPtr;
         m_pRefCnt = pRefCnt;

      // 参照カウンタを増加
      #if _DEBUG
         sprintf(c, "Upcase関数中で%08xの参照カウンタを増加\0", m_pPtr);
         AddRef(c);
      #else
         AddRef();
      #endif
   }


   // ==比較演算子
   BOOL operator ==(int val){
      if(m_pPtr == val)
         return TRUE;
      return FALSE;
   }

   // !=比較演算子
   BOOL operator !=(int val){
      if(m_pPtr != val)
         return TRUE;
      return FALSE;
   }
};