スポンサーリンク
検索

↑の検索エンジンが表示されない人は、
↓の古い検索エンジンを使用して下さい。
カスタム検索
MQL4リファレンスツリー
仮想関数


virtualキーワードは関数指定子です。
これは、実行時に基本クラスと派生クラスの関数から適切な関数を動的選択するメカニズムです。
構造体は仮想関数を持つ事は出来ません。
関数メンバの宣言を変更する為だけに使用する事が出来ます。

仮想関数は通常の関数のように実行可能な本体を持っている必要があります。
呼び出された時、そのセマンティックは他の関数と同じです。

仮想関数は派生クラスでオーバーライドする事が出来ます。
仮想関数の為にどの関数定義が選択されるかは動的(実行時)に行われます。
基本クラスに仮想関数が含まれているのが典型的なケースで、派生クラスはこの関数の独自のバージョンを持っています。

基本クラスへのポインタは、基本クラスオブジェクトまたは派生クラスオブジェクトのいずれかを示す事が出来きます。
呼び出すメンバ関数の選択は実行時に行われ、ポインタの型では無くオブジェクトの型に依存します。
派生型のメンバが無い場合は、基本クラスの仮想関数はデフォルトで使用されます。

デストラクタはvirtualキーワード宣言の有無に関係無く、常に仮想です。


例:
// 基本クラス
class CTetrisShape {

protected:
   int               m_type;
   int               m_xpos;
   int               m_ypos;
   int               m_xsize;
   int               m_ysize;
   int               m_prev_turn;
   int               m_turn;
   int               m_right_border;

public:
   void              CTetrisShape();
   void              SetRightBorder( int border) { m_right_border =  border;    }
   void              SetYPos( int ypos)          { m_ypos         =  ypos;      }
   void              SetXPos( int xpos)          { m_xpos         =  xpos;      }
   int               GetYPos()                  { return(m_ypos);              }
   int               GetXPos()                  { return(m_xpos);              }
   int               GetYSize()                 { return(m_ysize);             }
   int               GetXSize()                 { return(m_xsize);             }
   int               GetType()                  { return(m_type);              }
   void              Left()                     { m_xpos        -= SHAPE_SIZE; }
   void              Right()                    { m_xpos        += SHAPE_SIZE; }
   void              Rotate()                   { m_prev_turn   =  m_turn; if ( ++m_turn > 3 ) m_turn=0; }

   virtual void      Draw()                     { return;                      }
   virtual bool      CheckDown(  int& pad_array[]);
   virtual bool      CheckLeft(  int& side_row[]);
   virtual bool      CheckRight( int& side_row[]);
};



それぞれの派生クラスでは、この関数は下位クラスの特徴に応じて実装されます。
例えば最初の形状CTetrisShape1はDraw()関数が実装されます。


// 派生クラス(形状1)
class CTetrisShape1 : public CTetrisShape {

public:
   // 形状を描写する
   virtual void      Draw() {
      int    i;
      string name;

      if ( m_turn == 0 || m_turn == 2 ) {

         // 水平
         for ( i=0; i < 4; i++) {
            name = SHAPE_NAME + (string)i;
            ObjectSetInteger(0,name,OBJPROP_XDISTANCE, m_xpos + i * SHAPE_SIZE);
            ObjectSetInteger(0,name,OBJPROP_YDISTANCE, m_ypos );
         }
      } else {

         // 垂直
         for ( i=0; i < 4; i++ )
           {
            name = SHAPE_NAME + (string)i;
            ObjectSetInteger(0,name,OBJPROP_XDISTANCE, m_xpos );
            ObjectSetInteger(0,name,OBJPROP_YDISTANCE, m_ypos + i * SHAPE_SIZE);
         }
      }
   }
};



正方形形状はCTetrisShape6クラスで記述され独自のDraw()メソッドを実装します。


// 派生クラス(形状6 - 正方形)
class CTetrisShape6 : public CTetrisShape {

public:
   // 形状を描写する
   virtual void      Draw() {
      int    i;
      string name;

      for ( i=0; i < 2; i++) {
         name = SHAPE_NAME + (string)i;
         ObjectSetInteger(0,name,OBJPROP_XDISTANCE, m_xpos + i * SHAPE_SIZE);
         ObjectSetInteger(0,name,OBJPROP_YDISTANCE, m_ypos );
      }

      for ( i=2; i < 4; i++) {
         name = SHAPE_NAME + (string)i;
         ObjectSetInteger(0,name,OBJPROP_XDISTANCE, m_xpos + (i-2) * SHAPE_SIZE);
         ObjectSetInteger(0,name,OBJPROP_YDISTANCE, m_ypos + SHAPE_SIZE);
      }
   }
};



クラスに応じて作成されたオブジェクトが属します、それはこの仮想関数か派生クラスの仮想関数を呼び出します。



void CTetrisField::NewShape() {
   
   // 7つの可能な形状な物をランダムに作成
   int nshape = rand() % 7;

   switch( nshape ) {
      case 0: m_shape = new CTetrisShape1; break;
      case 1: m_shape = new CTetrisShape2; break;
      case 2: m_shape = new CTetrisShape3; break;
      case 3: m_shape = new CTetrisShape4; break;
      case 4: m_shape = new CTetrisShape5; break;
      case 5: m_shape = new CTetrisShape6; break;
      case 6: m_shape = new CTetrisShape7; break;
   }
   
   // 描画
   m_shape.Draw();

}




スポンサーリンク
スポンサーリンク


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


Top

inserted by FC2 system