photo
+ Responder ao Tópico
Resultados de 1 a 1 de 1

Thread: Funções Virtuais

  1. #1 Fechar a publicação
    Senior Member jssuser's Avatar jssuser's Avatar
    Data de afiliação
    Aug 2018
    Postagens
    1,503
    Obrigado
    209
    Agradecimentos 1,574 Tempos em 856 Postagens
    AssinarAssinar
    subscritar: 0

    Funções Virtuais

    A palavra-chave virtual é o especificador de função que fornece um mecanismo para selecionar dinamicamente em tempo de execução uma função-membro apropriada entre as funções de classes base e derivadas. Estrutura não podem ter funções virtuais. Pode ser usado para alterar as declarações de funções-membro somente.

    A função virtual, assim como uma função comum, deve ter um corpo executável. Ao ser chamada, sua semântica é a mesma que das outras funções.

    Uma função virtual pode ser sobreposta (overridden) em um classe derivada. A escolha de qual definição de função deve ser chamada para uma função virtual é feita dinamicamente (em tempo de execução). Um caso típico é quando uma classe base contém uma função virtual, e as classes derivadas têm sua própria versão desta função.

    O ponteiro para a classe base pode indicar tanto um objeto da classe base quanto um objeto de uma classe derivada. A escolha da função-membro a ser chamada será executada em tempo de execução e dependerá do tipo do objeto, não do tipo do ponteiro. Se não houver nenhum membro de um tipo derivado, a função virtual da classe base é usada por default.

    Destrutores são sempre virtuais, independentemente se elas estão declaradas com a palavra-chave virtual ou não.

    Vamos considerar o uso de funções virtuais no exemplo do MT5_Tetris.mq5. A classe base CTetrisShape com a função virtual de desenhar é definjida na inclusão do arquivo MT5_TetisShape.mqh.

    //+------------------------------------------------------------------+
    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[]);
    };

    Mais adiante, para cada classe derivada, esta função é implementada de acordo com as características da classe descendente. Por exemplo, a primeira forma CTetrisShape1 tem sua implementação própria da função Draw():

    class CTetrisShape1 : public CTetrisShape
    {
    public:
    //--- desenhando formato
    virtual void Draw()
    {
    int i;
    string name;
    //---
    if(m_turn==0 || m_turn==2)
    {
    //--- horizontal
    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
    {
    //--- vertical
    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);
    }
    }
    }
    }

    A forma Quadrado é descrita por meio da classe CTetrisShape6 e tem sua implementação própria do método Draw():

    class CTetrisShape6 : public CTetrisShape
    {
    public:
    //--- desenhando formato
    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+S HAPE_SIZE);
    }
    }
    };

    Dependendo da classe da qual o objeto criado pertence, é chamada a função virtual desta ou daquela classe derivada.

    void CTetrisField::NewShape()
    {
    //--- criando uma dos 7 possíveis formas aleatoriamente
    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;
    }
    //--- desenhar
    m_shape.Draw();
    //---
    }

    Though trading on financial markets involves high risk, it can still generate extra income in case you apply the right approach. By choosing a reliable broker such as InstaForex you get access to the international financial markets and open your way towards financial independence. You can sign up here.


  2. The Following User Says Thank You to jssuser For This Useful Post:

    Não registrado (1 )

+ Responder ao Tópico

Permissões de postagens

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts