Array クラスを作る (導入編)

C/C++ では、関数の引数・戻り値の型として、配列を扱うことができません。 なので、関数コールをまたいで配列データをやりとりしようとすると、配列の先頭アドレスとサイズの両方を渡して、必要ならバッファを動的に確保して、そこに要素値をコピー……という面倒な手順を踏む必要があります。
しかし、C++ を使っているのならば、自分で配列クラスを作ることでこの面倒を回避できます。

さて、C++ は静的な型付けを行う言語なので、動的型付け言語の PerlRuby のようにどんな型のオブジェクトでも混ぜこぜにして入れられるようなフザけた配列にはできません。
任意の型に対する配列型を定義するために、テンプレート機能を使います。
まずは、クラスの定義から:

//「配列」クラステンプレート
template <typename T> Array {
public:
//construction
Array();
Array(const Array<T>&);
explicit Array(int nSize);
//destruction
virtual ~Array();
virtual void Delete();
protected:
int m_nSize;
T*  m_lpa;
private:
//destruction
void Destroy();
};

データメンバ

データメンバは、要素数を格納する m_nSize と、配列領域の先頭アドレスを表す m_lpa の2つ。
扱い易さのため、これらのデータメンバには以下の制約を設けます。

  • m_nSize ≥ 0
  • m_nSize = 0 ⇔ m_lpa = NULL (i.e. m_nSize ≠ 0 ⇔ m_lpa ≠ NULL)

上記制約の導入には、次のようなメリット (?) があります。

  • オブジェクトのメモリ領域をゼロクリアすると、デフォルトの状態になる。
  • キャスト演算子による T* ないし const T* 型への変換 (後述) により、空/非空判定が容易になる。

メンバ関数

メンバ関数の定義 (実装) については、後続のエントリで少しずつ紹介・解説していきます。