OLP. Questões de aplicação - página 5

 

De alguma forma, a questão de saber se o multi-purposeing afecta ou não a velocidade do processamento de códigos pelo processador(2011.04.04 21:58) é deixada completamente sem vigilância.

Se a pergunta parecer incorrecta, idiota, etc. - então escreva assim.

 
Yedelkin:

De alguma forma, a questão de saber se o multi-purposeing afecta ou não a velocidade de processamento do código do processador(2011.04.04 21:58) é deixada completamente desacompanhada.

Se a pergunta parecer incorrecta, idiota, etc. - basta escrevê-lo.

A pergunta é perfeitamente lógica, a resposta é não, não é.

2011.04.09 10:21:31     Черновик 31 (GBPUSD,H1) время c обёртками=1656
2011.04.09 10:21:29     Черновик 31 (GBPUSD,H1) время без обёртки=1766


class CA
  {
private:
   uint              func1(int count){return(func2(count));};
   uint              func2(int count){return(func3(count));};
   uint              func3(int count){return(func4(count));};
   uint              func4(int count){return(func5(count));};
   uint              func5(int count){return(func6(count));};
   uint              func6(int count){return(func7(count));};
   uint              func7(int count){return(func8(count));};
   uint              func8(int count){return(func9(count));};
   uint              func9(int count)
     {
      uint start=GetTickCount();
      double a=123456.4567879;double b=234.568;double temp;
      for(int i=0;i<count;i++)
        {
         if(i%2==0)temp=a/b;
         else temp=a*b;
        }
      return(GetTickCount()-start);
     };
public:
                     CA(void){};
                    ~CA(void){};
   uint              func(int count){return(func1(count));};

  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnStart()
  {
//---
          Print("время без обёртки=",  func(100000000));
   CA a; Print("время c обёртками=",a.func(100000000));
  }
//+------------------------------------------------------------------+
uint func(int count)
  {
   uint start=GetTickCount();
   double a=123456.4567879;double b=234.568;double temp;
   for(int i=0;i<count;i++)
     {
      if(i%2==0)temp=a/b;
      else temp=a*b;
     }
   return(GetTickCount()-start);
  }
//+------------------------------------------------------------------+
 

Consegui! Bem, deu-me um grande incentivo! Vou agora duplicar o prazer de estampar métodos aninhados :)

Urain, obrigado pelo exemplo! Embora não tenha experiência de programação, por vezes é difícil adivinhar-se a si próprio para verificar e escrever o código correcto para isso. E aqui tudo é claro e compreensível.

 

Pergunta. Pode uma instância de uma classe infantil apagar-se a si própria? Por outras palavras, será que uma tal construção vai funcionar?

class C_A
  {
public:
                     C_A(){};
                    ~C_A(){};
   void Del(C_A *p)
     {
      if(CheckPointer(p)==POINTER_DYNAMIC)
        {
         delete p;
        }
     }
  };
class C_B : public C_A
  {
public:
                     C_B(){};
                    ~C_B(){};
  };
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   C_A *pointer=new C_B;
   pointer.Del(pointer);
  }
O compilador não se queixa desta construção.
 
Yedelkin:

Pergunta. Pode uma instância de uma classe infantil apagar-se a si própria? Por outras palavras, será que esta construção vai funcionar?

O compilador não se queixa desta construção.

Se bem entendi, não gosto de apontadores (e não os uso frequentemente, especialmente em MQL5), a criança deve ter este aspecto

class C_B : public C_A
{
public:
                     C_B(){};
                    ~C_B(){};

   void Del(C_B *p)
     {
      if(CheckPointer(p)==POINTER_DYNAMIC)
        {
         delete p;
        }
     }
};

Por conseguinte, o pedido teria o seguinte aspecto

void OnStart()
{
C_B *pointer=new C_B;
pointer.Del(pointer);
}

PS

É um erro (ou uma característica do compilador) o facto de o compilador o ter perdido?

Claro, podemos assumir que o descendente passou a classe de que precisamos, mas as estruturas e funcionalidade das duas classes podem ser muito diferentes. Então, o que acontece?

C_A *pointer=new C_B;
 

E quando se utiliza o código inicial como este, ocorre uma fuga de memória, embora todas as verificações do compilador tenham sido aprovadas (e nem sequer foi mencionado qualquer problema possível)

void OnStart()
{
C_B *pointer=new C_B;
pointer.Del(pointer);
}

Aqui está o resultado (entendo que o objecto ponteiro não é correctamente apagado por causa da fuga de memória):

2011.04.09 19:21:07    Forum (EURUSD,D1)    16 bytes of leaked memory
2011.04.09 19:21:07    Forum (EURUSD,D1)    1 object of type C_B left
2011.04.09 19:21:07    Forum (EURUSD,D1)    1 undeleted objects left
 
Interesting:

Se o entendi correctamente, não gosto de apontadores (e não os uso frequentemente, especialmente na MQL5), então o descendente deve ter o seguinte aspecto

Veja. Declarei nulo o método Del(C_A *p) com modificador público na classe mãe. Assim, a classe infantil herdou totalmente este método. Por isso, não preciso de reprovar o mesmo método na classe infantil. Quanto a
C_A *pointer=new C_B;
Tive esta ideia com o tetris, e funciona muito bem para mim. Claro que não seria correcto utilizar esta linha de forma directa, mas é muito adequada para fins semelhantes aos que se resolvem em tetris.
 
Yedelkin:

De alguma forma, a questão de saber se o multi-purposeing afecta ou não a velocidade do processamento de códigos pelo processador(2011.04.04 21:58) é deixada completamente sem vigilância.

Se a pergunta parecer incorrecta, idiota, etc. - basta escrevê-lo.

A resposta à lógica - quanto mais simples e mais lógicos os primitivos, mais eficiente será o optimizador.

O principal é não exagerar :)

 

Ligeiramente modificado o código do guião:

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class C_A
  {
public:
                     C_A(){ Print("Запущен класс С_А"); };
                    ~C_A(){Print("Закрыт класс С_А");};
   void Del(C_A *p)
     {
      if(CheckPointer(p)==POINTER_DYNAMIC)
        {
         delete p;
         Print("Удалён объект p");
        }
     }
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class C_B : public C_A
  {
public:
                     C_B(){ Print("Запущен класс С_В"); };
                    ~C_B(){Print("Закрыт класс С_В");};
  };
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   C_A *pointer=new C_B;
   if(pointer!=NULL) Print("указатель pointer проинициализирован");
   pointer.Del(pointer);
  }

Saídas

EL      0       ttttttttttttt (EURUSD,M1)       15:08:27        Запущен класс С_А
MS      0       ttttttttttttt (EURUSD,M1)       15:08:27        Запущен класс С_В
DJ      0       ttttttttttttt (EURUSD,M1)       15:08:27        указатель pointer проинициализирован
IH      0       ttttttttttttt (EURUSD,M1)       15:08:27        Закрыт класс С_В
CG      0       ttttttttttttt (EURUSD,M1)       15:08:27        Закрыт класс С_А
RO      0       ttttttttttttt (EURUSD,M1)       15:08:27        Удалён объект p
 
Yedelkin:
Veja. Declarei nulo o método Del(C_A *p) com modificador público na classe mãe. Assim, a classe infantil herdou totalmente este método. Por isso, não preciso de reprovar o mesmo método na classe infantil. Quanto a esta ideia, obtive-a de tetris e funcionou muito bem para mim. Claro que não seria correcto utilizar este cordel de forma directa, mas é muito adequado para fins semelhantes aos que se resolvem em tetris.

Mesmo assumindo que o Del(C_A *p) vazio no antepassado é suficiente para apagar qualquer ponteiro descendente, não vejo sentido em usar

C_A *pointer=new C_B;

PS

O único local onde posso imaginar a necessidade de tal abordagem é a criação de um conjunto de objectos diversos que são descendentes da mesma classe (em alternativa, passando um parâmetro do tipo de classe "base" para uma função ou procedimento).