/*** xarray.h ヘッダファイル ***/ @
/*** XArray クラスの宣言 ***/
class XArray
{
private: A
int *item; // 先頭要素へのポインタ D
protected: A
static int size; // サイズ DE
public: A
// コンストラクタとデストラクタ
XArray(); B
XArray(const XArray *a); B
~XArray(); C
// メンバ関数
static int GetSize(); DE
int GetItem(int index); D
void SetItem(int index, int value); D
};
/*** xarray.cpp ソースファイル ***/
#include <memory.h> // memcpy
#include "xarray.h" @ // XArrayクラス
/*** XArray クラスの実装 ***/ F
// 静的メンバ変数
int XArray::size = 100; E
// 静的メンバ:サイズの取得 DE
int XArray::GetSize()
{
return size;
}
// コンストラクタ B
XArray::XArray()
{
item = new int[size];
}
// コピー・コンストラクタ B
XArray::XArray(const XArray *a)
{
Gthis->item = new int[size];
Gmemcpy(this->item,
a->item, sizeof(int) * size);
}
// デストラクタ C
XArray::~XArray()
{
delete [] item;
}
// メンバ関数:値の取得 D
int XArray::GetItem(int index)
{
if (index >= 0 && index < size) {
return *(item + index);
} else {
return -1;
}
}
// メンバ関数:値の設定 D
void XArray::SetItem(int index, int value)
{
if (index >= 0 && index < size) {
*(item + index) = value;
}
}
/*** main.cpp ソースファイル ***/
#include <stdio> // printf
#include <conio.h> // getch
#include "xarray.h" @ // XArrayクラス
// main 関数
void main()
{
int i;
int n = XArray::GetSize(); //サイズ E
XArray a; B
for (i=0; i<n; i++) {
a.SetItem(i, i*2); // 値の設定 D
}
XArray x(&a); // コピーコンストラクタ B
for (i=0; i<n; i++) {
printf("%d,", x.GetItem(i)); //出力 D
}
if (getch()) return 0;
} |
【@クラスの宣言】
通例、クラスの宣言はヘッダファイルに記述し、実装(関数の中身など)はソースファイルで行います。宣言だけでは実体はつくられません。使用する時は、 #include "xarray.h" のように、ヘッダファイルをインクルードします。
【Aアクセス修飾子】
クラスでは、データの保護や公開をアクセス修飾子で制御することができます。
| | クラス内部 | 派生クラス | クラス外部 |
| private | ○ | × | × |
| protected | ○ | ○ | × |
| public | ○ | ○ | ○ |
private は省略可能ですが、いずれのアクセス修飾子も、定義の末端か次のアクセス修飾子までが有効範囲です。また、同じアクセス修飾子を繰返し記述することも可能です。
【Bコンストラクタ】
クラスは、インスタンス(実体)が作成されると、まずコンストラクタが呼ばれます。コンストラクタの定義は必須ではありませんが、定義する時は次のルールに則って記述し、変数などの初期化を行います。
・ コンストラクタ名はクラス名と同じにする
・ コンストラクタはまったく値を返さないこと
コンストラクタは引数を取ることができますが、引数のない既定のコンストラクタは必要です。 サンプルでは、引数の異なる2つのコンストラクタが定義 ( = オーバーロード ) されています。このうち2つ目は、特にコピー・コンストラクタと呼ばれ、自クラスのインスタンス(実体)を参照してコピーする機能を持ちます。 また、コンストラクタにおけるメンバの初期化は、以下のように明示的に行うことができます。
XArray::XArray():item(NULL) { ... }
なお、配列にした時に呼び出すことができるのは、既定のコンストラクタだけです。
【Cデストラクタ】
クラスでは、実体が破棄される時は、自動的にデストラクタが呼ばれます。デストラクタの定義は必須ではありませんが、定義する時は次のルールに則ってデストラクタを記述し、メモリの解放などの終了処理を行います。
・ デストラクタ名はクラス名の頭に ~ を付ける
・ デストラクタはまったく値を返さないこと
* コンストラクタとデストラクタに データ型や return文の記述をすることはできません。
【Dメンバ】
クラスで独自に定義された要素を メンバ と呼びます。メンバには、データメンバ(変数・定数)とメンバ関数とがあります。 メンバは、通常は " インスタンス名 . メンバ " 、ポインタの場合は " インスタンス名 -> メンバ " のようにしてアクセスします。
* サンプルのように、メンバ変数は private や protected で保護し、外部関数からのアクセスの際には、メンバ関数を経由して、内部でチェックしてから使用すると安全に使用できます。
【E静的メンバ】
static をつけたメンバは、特に静的メンバと呼ばれ、すべてのインスタンス(実体)で共通に適用する値、または関数となります。 静的メンバは、実装時に値を初期化しておくことが可能です。また、クラスのインスタンスがなくても、"クラス名 :: 静的メンバ" のように、インスタンス名を用いずにアクセスすることができます。ただし、静的メンバ関数内では、静的メンバ以外のメンバを使用することはできません。
【Fクラスの実装】
関数の中身は、一行程度であれば宣言時に記述することがあります(次節のサンプルコードの宣言部を参照)が、通常はソースファイルに記述します。 別ファイルに実装定義を記述する際は、特定のクラスのメンバ関数であることを示すために、関数名の前に "クラス名 :: " の記述が必要です。
【Gthisポインタ】
サンプルコードで、メンバの前にある "this->" は thisポインタです。インスタンス(実体)が作成された時の自分を指す機能を持ちます。thisポインタは省略可能ですが、コピー・コンストラクタの中の、 "a->item, this->item" のように、他のインスタンスと区別する際に使用します。
|