トップ  >  リファレンス  >  基本  >  オブジェクト指向プログラミング  >  クラス/構造体の静的メンバ
スポンサーリンク
検索
カスタム検索
リファレンスツリー
オススメ
クラス/構造体の静的メンバ


静的メンバ

クラスのメンバはstatic修飾子を使用して宣言する事が出来ます。
これらのデータメンバは、このクラスの全てのインスタンスで共有され、1つの場所に格納されます。
非静的データメンバは各クラスのオブジェクト変数の為に作成されます。

クラスの静的メンバを宣言する事が出来なければ、プログラムのグローバルレベルでこれらのデータを宣言する事が必要になります。
これはデータとクラスの間の関係を壊します、そしてOOPの基本的なパラダイム(クラスでデータとそれらを処理する為のメソッドを結合する)と一致しません。
静的メンバは、クラススコープ内に特定インスタンス固有でないクラスデータの存在を可能にします。

静的クラスメンバは特定インスタンスに依存しないので、参照方法は次の通りになります。



クラス名::クラスメンバ名



ご覧の通り、クラスの静的メンバにアクセスするにはスコープ解決演算子(::)を使用します。
クラスメソッド内の静的メンバにアクセスする際には演算子は任意になります。

クラスの静的メンバは明示的に初期値を設定する必要があります。
この為、グローバルスコープで宣言・初期化しなければなりません。
静的メンバの初期化順は、グローバルスコープでの宣言順に対応します。

例えば、テキスト解析するCParserクラスがあり、単語や文字の処理合計数をカウントする必要があるとします。
静的クラスメンバを宣言し、グローバルレベルでそれらを初期化する必要があります。
そしてクラスの全インスタンスは単語や文字の共通カウンタを使用します。


//+------------------------------------------------------------------+
//| テキスト解析クラス                                          
//+------------------------------------------------------------------+
class CParser {

public:
   static int        s_words;
   static int        s_symbols;

   // コンストラクタとデストラクタ
                     Parser(void);
                    ~Parser(void){};
};

〜中略〜

// グローバルレベルでのCParserクラスの静的メンバの初期化
int CParser::s_words   = 0;
int CParser::s_symbols = 0;




静的クラスメンバはconstキーワードで宣言する事が出来ます。
このような静的定数はconstキーワードを持つグローバルレベルで初期化する必要があります。


class CStack {

public:
                     CStack(void);
                    ~CStack(void){};

〜中略〜

private:
   static const int  s_max_length; // 最大スタック容量

};

// CStackクラスの静的定数の初期化
const int CStack::s_max_length = 1000;




thisポインタ

thisキーワードは自分自身(メソッドが実行されたコンテキスト内のクラスの特定インスタンス)に暗黙的に宣言されたポインタを示します。
これはクラスの非静的メソッドでのみ使用する事が出来ます。
ポインタはクラスの暗黙的な非静的メンバです。

静的メソッド

MQL4では静的メンバ関数を使用する事が出来ます。
static修飾子は、クラス内の宣言で関数の戻り値型を先行しなければなりません。



class CStack {

public:
   // コンストラクタとデストラクタ
                     CStack(void){};
                    ~CStack(void){};

   // 最大スタック容量
   static int        Capacity();

private:
   int                 m_length;     // スタックの要素数
   static const int  s_max_length; // 最大スタック容量
};

//+------------------------------------------------------------------+
//| スタックに格納出来る最大要素数を返します
//+------------------------------------------------------------------+
int CStack::Capacity(void) {
   return( s_max_length );
}

// CStackクラスの静的定数の初期化
const int CStack::s_max_length = 1000;

//+------------------------------------------------------------------+
//| スクリプトプログラムスタートイベント
//+------------------------------------------------------------------+
void OnStart() {
   // CStack型変数を宣言
   CStack stack;

   // オブジェクトの静的メソッドを呼び出す
   Print("CStack.s_max_length = ",stack.Capacity());

   // メソッドが静的で、オブジェクトの存在を必要としない為、次のように呼び出せます
   Print("CStack.s_max_length = ",CStack::Capacity());
}



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);// { return(w * h); }
};

//+------------------------------------------------------------------+
//| 長方形オブジェクトの面積を返す                       
//+------------------------------------------------------------------+
double CRectangle::Square(void) const {
   return( Square(m_width , m_height) );
}

//+------------------------------------------------------------------+
//| 2つの変数の積を返す                             
//+------------------------------------------------------------------+
static double CRectangle::Square(const double w,const double h) {
   return(w * h);
}

//+------------------------------------------------------------------+
//| スクリプトプログラムスタートイベント                                    
//+------------------------------------------------------------------+
void OnStart() {

   // 側面が5と6の長方形rectを作成
   CRectangle rect(5,6);

   // 定数メソッドを使用して長方形面積を見つけます
   PrintFormat("rect.Square()=%.2f",rect.Square());

   // CRectangleクラスの静的メソッドを使用して、数値を見つける
   PrintFormat("CRectangle::Square(2.0,1.5) = %f",CRectangle::Square(2.0,1.5));
}



定数制御を使用するもう一つの利点は、コンパイラが特別な最適化(例えば読み出し専用メモリに定数オブジェクトを配置する)を生成する場合です。

静的関数はconst修飾子を用いる事は出来ません。なせならこの修飾子はその関数を呼び出す時にこのインスタンスメンバーの不変をを保証するからです。
しかし前途したように、静的関数は非静的クラスメンバにアクセスする事は出来ません。

■関連コンテンツ:
静的変数
参照:&修飾子とthis
スポンサーリンク



Copyright ©2015 MT4でEA自作しちゃお〜 All Rights Reserved.


Top

inserted by FC2 system