OLP. Problemas de aplicación - página 5

 

De alguna manera, la cuestión de si la multipropiedad afecta o no a la velocidad de procesamiento del código por parte del procesador(2011.04.04 21:58) queda completamente desatendida.

Si la pregunta parece incorrecta, tonta, etc. - entonces escribe así.

 
Yedelkin:

De alguna manera, la cuestión de si la multipropiedad afecta o no a la velocidad de procesamiento de código del procesador(2011.04.04 21:58) queda completamente desatendida.

Si la pregunta parece incorrecta, tonta, etc. - sólo escríbelo así.

La pregunta es perfectamente lógica, la respuesta es no, no lo hace.

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

¡Ya lo tengo! Bueno, ¡me has dado muchos ánimos! Ahora voy a duplicar el placer de estampar métodos anidados :)

Urain, ¡gracias por el ejemplo! Mientras no tengas experiencia en programación, a veces es difícil adivinar por ti mismo para comprobar y escribir un código correcto para ello. Y aquí todo es claro y comprensible.

 

Pregunta. ¿Puede una instancia de una clase hija borrarse a sí misma? En otras palabras, ¿funcionará esta construcción?

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);
  }
El compilador no se queja de esta construcción.
 
Yedelkin:

Pregunta. ¿Puede una instancia de una clase hija borrarse a sí misma? En otras palabras, ¿funcionará esta construcción?

El compilador no se queja de esta construcción.

Si lo he entendido bien, no me gustan los punteros (y no los uso a menudo, sobre todo en MQL5), el hijo debería ser así

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

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

Por lo tanto, la aplicación tendría el siguiente aspecto

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

PS

¿Es un error (o una característica del compilador) que el compilador pasó por alto?

Por supuesto, podemos asumir que el descendiente pasó la clase que necesitamos, pero las estructuras y la funcionalidad de las dos clases podrían ser muy diferentes. ¿Qué ocurre entonces?

C_A *pointer=new C_B;
 

Y al utilizar el código inicial así, se produce una fuga de memoria en absoluto, aunque se han pasado todas las comprobaciones del compilador (y ni siquiera ha mencionado ningún posible problema)

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

Este es el resultado (entiendo que el objeto puntero no se borra correctamente por la fuga de memoria):

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:

Si lo entiendo bien, no me gustan los punteros (y no los uso a menudo, especialmente en MQL5), entonces el descendiente debería ser así

Mira. He declarado el método void Del(C_A *p) con el modificador public en la clase padre. Por lo tanto, la clase hija ha heredado completamente este método. Así no necesito volver a declarar el mismo método en la clase hija. En cuanto a
C_A *pointer=new C_B;
Esta idea la saqué del tetris, y me funciona muy bien. Por supuesto, no sería correcto utilizar esta línea sin más, pero es muy adecuada para fines similares a los que se resuelven en el tetris.
 
Yedelkin:

De alguna manera, la cuestión de si la multipropiedad afecta o no a la velocidad de procesamiento de código del procesador(2011.04.04 21:58) queda completamente desatendida.

Si la pregunta parece incorrecta, tonta, etc. - sólo escríbelo.

La respuesta a la lógica: cuanto más simples y lógicas sean las primitivas, más eficiente será el optimizador.

Lo principal es no exagerar :)

 

Se ha modificado ligeramente el código del script:

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

Salidas

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:
Mira. Declaré el método void Del(C_A *p) con el modificador public en la clase padre. Así que la clase hija ha heredado completamente este método. Así no necesito volver a declarar el mismo método en la clase hija. En cuanto a esta idea, la saqué del tetris y me funcionó muy bien. Por supuesto, no sería correcto utilizar esta cadena sin más, pero es muy adecuada para fines similares a los que se resuelven en el tetris.

Incluso asumiendo que void Del(C_A *p) en el ancestro es suficiente para borrar cualquier puntero descendiente, no veo el sentido de usar

C_A *pointer=new C_B;

PS

El único lugar donde puedo imaginar la necesidad de tal enfoque es la creación de una matriz de objetos diversos que son descendientes de la misma clase (alternativamente, pasando un parámetro del tipo de clase "base" en una función o procedimiento).