静的メンバ
クラスのメンバは
static修飾子を使用して宣言する事が出来ます。
これらのデータメンバは、このクラスの全てのインスタンスで共有され、1つの場所に格納されます。
非静的データメンバは各クラスのオブジェクト変数の為に作成されます。
クラスの静的メンバを宣言する事が出来なければ、プログラムの
グローバルレベルでこれらのデータを宣言する事が必要になります。
これはデータとクラスの間の関係を壊します、そしてOOPの基本的なパラダイム(クラスでデータとそれらを処理する為のメソッドを結合する)と一致しません。
静的メンバは、クラススコープ内に特定インスタンス固有でないクラスデータの存在を可能にします。
静的クラスメンバは特定インスタンスに依存しないので、参照方法は次の通りになります。
クラス名::クラスメンバ名
ご覧の通り、クラスの静的メンバにアクセスするには
スコープ解決演算子(::)を使用します。
クラスメソッド内の静的メンバにアクセスする際には演算子は任意になります。
クラスの静的メンバは明示的に初期値を設定する必要があります。
この為、グローバルスコープで宣言・初期化しなければなりません。
静的メンバの初期化順は、グローバルスコープでの宣言順に対応します。
例えば、テキスト解析するCParserクラスがあり、単語や文字の処理合計数をカウントする必要があるとします。
静的クラスメンバを宣言し、グローバルレベルでそれらを初期化する必要があります。
そしてクラスの全インスタンスは単語や文字の共通カウンタを使用します。
静的クラスメンバは
constキーワードで宣言する事が出来ます。
このような静的定数は
constキーワードを持つグローバルレベルで初期化する必要があります。
thisポインタ
thisキーワードは自分自身(メソッドが実行されたコンテキスト内のクラスの特定インスタンス)に暗黙的に宣言された
ポインタを示します。
これはクラスの非静的メソッドでのみ使用する事が出来ます。
ポインタはクラスの暗黙的な非静的メンバです。
静的メソッド
MQL4では静的メンバ関数を使用する事が出来ます。
static修飾子は、クラス内の宣言で関数の戻り値型を先行しなければなりません。
const修飾子を持つメソッドは定数と呼ばれ、そのクラスの暗黙メンバを変更する事は出来ません。
クラスの定数関数と定数パラメータの宣言はconstコレクトネス制御と呼ばれます。
この制御により、コンパイラがオブジェクトの値の整合性を確保する事を確認でき、問題がある場合はコンパイル時にエラーを返します。
const修飾子はクラス宣言内部の引数リストの後に配置されます。
クラスの外部定義はconst修飾子を含める必要があります。
class CRectangle {
private:
double m_width;
double m_height;
public:
CRectangle(void):m_width(0), m_height(0){};
CRectangle(const double w, const double h):m_width(w), m_height(h){};
~CRectangle(void){};
double Square(void) const;
static double Square(const double w,const double h);
};
double CRectangle::Square(void) const {
return( Square(m_width , m_height) );
}
static double CRectangle::Square(const double w,const double h) {
return(w * h);
}
void OnStart() {
CRectangle rect(5,6);
PrintFormat("rect.Square()=%.2f",rect.Square());
PrintFormat("CRectangle::Square(2.0,1.5) = %f",CRectangle::Square(2.0,1.5));
}
定数制御を使用するもう一つの利点は、コンパイラが特別な最適化(例えば読み出し専用メモリに定数オブジェクトを配置する)を生成する場合です。
静的関数は
const修飾子を用いる事は出来ません。なせならこの修飾子はその関数を呼び出す時にこのインスタンスメンバーの不変をを保証するからです。
しかし前途したように、静的関数は非静的クラスメンバにアクセスする事は出来ません。