Array.h |
---|
// Array.h #ifndef __ARRAY_H__INCLUDED__ #define __ARRAY_H__INCLUDED__ #include <iostream.h> #include <stdlib.h> template <typename TYPE> class CArray { // メンバ変数 private: TYPE* m_pnum; // 動的配列 int m_nNumOf; // 配列の要素数 // コンストラクタ・デストラクタ public: explicit CArray(const int nNumOf); CArray(const CArray <TYPE> & rother); // コピーコンストラクタ virtual ~CArray(); // メンバへのアクセス関数 public: TYPE Get(const int index) const; void Set(const int index, const TYPE value); // メンバの参照 TYPE& operator [](unsigned int index); TYPE& operator [](int index); TYPE operator [](unsigned int index) const; TYPE operator [](int index) const; operator const TYPE*() const; // 配列の直接参照 // インデックスのチェック private: void CheckIndex(const int index) const; // その他の情報の取得 public: bool IsValid() const; // m_pnum の値が有効かどうか int NumOf() const; // 配列の要素数 int SizeOf() const; // 配列のサイズ // コピー public: bool Copy(const CArray <TYPE> & rother); // 配列のコピー CArray <TYPE> & operator =(const CArray <TYPE> & rother); // = 演算子のオーバーロード // 諸関数 private: void Init(); // メンバの初期化 void Release(); // メモリの解放 }; // m_pnum の値が有効かどうか // inline はやはり template の後に書きます template <typename TYPE> inline bool CArray <TYPE> ::IsValid() const { return m_pnum != NULL; } // 配列の要素数 template <typename TYPE> inline int CArray <TYPE> ::NumOf() const { return m_nNumOf; } // 配列のサイズ template <typename TYPE> inline int CArray <TYPE> ::SizeOf() const { // sizeof を使っていれば、 // どんな型が来てもきちんとした値が得られます return m_nNumOf * sizeof *m_pnum; } // 配列の直接参照 // TYPE 型への配列を返すので、 // もちろんキャスト演算子は (const TYPE*) となります template <typename TYPE> inline CArray <TYPE> ::operator const TYPE*() const { return m_pnum; } // コンストラクタ template <typename TYPE> CArray <TYPE> ::CArray(const int nNumOf) { // TYPE 型で new します // クラスの配列を作るときでもコンストラクタが呼ばれます m_pnum = new TYPE[nNumOf]; if(m_pnum == NULL) m_nNumOf = 0; else m_nNumOf = nNumOf; // 0 での初期化は行わないことにします // クラスの配列を扱う際に問題になるからです } // コピーコンストラクタ template <typename TYPE> CArray <TYPE> ::CArray(const CArray <TYPE> & rother) { Init(); Copy(rother); } // デストラクタ template <typename TYPE> CArray <TYPE> ::~CArray() { Release(); } // メンバへのアクセス関数 template <typename TYPE> TYPE CArray <TYPE> ::Get(const int index) const { CheckIndex(index); return m_pnum[index]; } template <typename TYPE> void CArray <TYPE> ::Set(const int index, const TYPE value) { CheckIndex(index); m_pnum[index] = value; } // インデックスのチェック template <typename TYPE> void CArray <TYPE> ::CheckIndex(const int index) const { if((unsigned int)index < (unsigned int)m_nNumOf) return; cout << "インデックスが不正です!" << endl << "値 : " << index << endl; exit(1); } // メンバの参照 template <typename TYPE> TYPE& CArray <TYPE> ::operator [](unsigned int index) { CheckIndex(index); return m_pnum[index]; } // メンバの参照 template <typename TYPE> inline TYPE& CArray <TYPE> ::operator [](int index) { // ちょっと強引でしょうか? return (*this)[(unsigned int)index]; } // メンバの参照 template <typename TYPE> TYPE CArray <TYPE> ::operator [](unsigned int index) const { CheckIndex(index); return m_pnum[index]; } // メンバの参照 template <typename TYPE> inline TYPE CArray <TYPE> ::operator [](int index) const { return (*this)[(unsigned int)index]; } // 配列のコピー template <typename TYPE> bool CArray <TYPE> ::Copy(const CArray <TYPE> & rother) { // 自分自身はコピーしない if(this == &rother) return true; Release(); // 配列が確保されているときはメモリを解放 if(rother.IsValid() == true) { m_pnum = new TYPE[rother.NumOf()]; if(m_pnum == NULL) { m_nNumOf = 0; return false; } m_nNumOf = rother.m_nNumOf; // コピーは = 演算子を使って行います // クラスを扱うときに問題になるからですね for(int i = 0; i < m_nNumOf; i++) m_pnum[i] = rother[i]; } return true; } // = 演算子によるコピー // もちろんテンプレート引数は戻り値の型にも必要です template <typename TYPE> CArray <TYPE> & CArray <TYPE> ::operator =(const CArray <TYPE> & rother) { Copy(rother); return *this; } // メンバの初期化 template <typename TYPE> void CArray <TYPE> ::Init() { m_pnum = NULL; m_nNumOf = 0; } // メモリの解放 // 配列が確保されているときだけメモリを解放します // 解放した後はメンバを初期化します template <typename TYPE> void CArray <TYPE> ::Release() { if(IsValid() == true) { delete [] m_pnum; Init(); } } #endif // #ifnde __ARRAY_H__INCLUDED__ |
Last update was done on 2000.12.7
この講座の著作権はロベールが保有しています