Errores, fallos, preguntas - página 1891

 
Renat Fatkhullin:

Claro que sí.

¿Está seguro? Porque dynamic_cast se utiliza más a menudo para la conversión ascendente, de padre a hijo.

Además, en MQL echa perfectamente de abajo a arriba, incluso cuando no debería:

class A
{
public:
   virtual void f()
   {
      Print("1");
   }
};

class B: public A
{
public:
   virtual void f()
   {
      Print("2");
   }
};

void OnStart()
{
   A* ptr1 = new B();
   ptr1.f();
   A* ptr2 = new A();
   ptr2.f();
   
   B* casted = dynamic_cast<B*>(ptr1);
   casted.f();
   
   B* casted1 = dynamic_cast<B*>(ptr2);
   casted1.f(); // здесь должна быть ошибка потому что casted1 должен быть null
   delete ptr1;
   delete ptr2;
}

вывод:
2017.05.13 18:30:14.864    t ETHUSD,M5: 2
2017.05.13 18:30:14.865    t ETHUSD,M5: 1
2017.05.13 18:30:14.866    t ETHUSD,M5: 2
2017.05.13 18:30:14.867    t ETHUSD,M5: 2


Renat Fatkhullin:

Echa un vistazo al fragmento de código MQL5 comentado.

Sí, no debería funcionar y ya está explicado más arriba, pero no porque el reparto ascendente sea imposible.

 
Konstantin:
Si lanzamos el puntero de arriba a abajo, es decir, al padre, después de lo cual pasamos el puntero a otro lugar del ámbito, ¿los campos del descendiente estarán disponibles allí?

Sí, aquí hay un ejemplo que demuestra su pregunta:

class CLASS1
  {
public:
   int               i;
  };
class CLASS2 : public CLASS1
  {
  };
void OnStart()
  {
   CLASS1 _object;
   CLASS2 *_ptr=dynamic_cast<CLASS2 *>(&_object);

   if(!_ptr)
      Print("CLASS1 -> CLASS2 failed, null");

   CLASS2 *my=new CLASS2;
   CLASS1 *my_ptr=my;
   CLASS2 *my_ptr2=dynamic_cast<CLASS2 *>(my_ptr);

   if(my_ptr2)
     {
      Print("CLASS2 -> CLASS1 -> CLASS2 ok");
      my_ptr2.i=1;
     }
   Print("Value: ",my.i);
  }
y la salida:
2017.05.13 18:34:50.341 cast (EURUSD,H1)        CLASS1 -> CLASS2 failed, null
2017.05.13 18:35:18.933 cast (EURUSD,H1)        CLASS2 -> CLASS1 -> CLASS2 ok
2017.05.13 18:35:20.110 cast (EURUSD,H1)        Value: 1

En primer lugar, comprobamos el reparto no resuelto de abajo hacia arriba y obtenemos NULL. Esto es correcto.

Entonces creamos un objeto CLASS2, le asignamos una referencia a su clase padre (aquí es importante entender que dinámicamente el entorno sabe que el tipo original del objeto CLASS2 está almacenado en su meta-información). A continuación (sólo su pregunta), se hace un casting dinámico (con la comprobación de la conversión correcta basada en la metainformación del objeto de origen) de la referencia CLASS1 a CLASS2.

Comprobamos el resultado del casting y lo escribimos en la variable i = 1. Por último, se emite el valor de i, haciendo referencia al objeto creado originalmente.

Todo funciona correctamente y de acuerdo con la especificación (incluida la especificación dynamic_cast del propio C++).

 
Комбинатор:

¿Está seguro? Porque dynamic_cast se utiliza más a menudo para la conversión ascendente, de padre a hijo.

Además, en MQL echa perfectamente de abajo a arriba, incluso cuando no debería:

Exactamente:

No olvides actualizar a las últimas versiones. Actualmente estoy probando en el 1598, que fue publicado recientemente como una versión comprimida en este hilo, creo.

 
Renat Fatkhullin:

No olvides actualizar a las últimas versiones.

Sí, la antigua construcción.

Renat Fatkhullin:

Así es, no se puede conducir de abajo a arriba, sólo de arriba a abajo. Esto es por seguridad.

Deberías borrar este, es engañoso y contradice directamente el funcionamiento de dynamic_cast
 
Комбинатор:

Sí, la antigua construcción.

Borra esto, es engañoso y contradice directamente el funcionamiento de dynamic_cast

Como parte del ejemplo de reparto de CLASE1 -> CLASE2 planteado, has acertado. Ese es el tipo de casting que la mayoría de las veces la gente tiene en la cabeza.

Además, el "no se puede lanzar de abajo a arriba, sólo de arriba a abajo" es el núcleo de la comprobación de seguridad de dynamic_cast.

Los que saben lo que hacen entienden la esencia del dynamic_casting.

 
Renat Fatkhullin:

No olvides actualizar a las últimas versiones. Actualmente estoy probando en el 1598, que fue publicado recientemente como un zip en este hilo creo.

¿En qué archivo exe se encuentra el compilador y el ejecutor?

Ahora mismo MT4b1080 está ejecutando MEb1599. Por favor, explica qué hacen metaeditor.exe y terminal.exe.

 
fxsaber:

¿En qué archivo exe se encuentra el compilador y el ejecutor?

El MT4b1080 está ahora ejecutando MEb1599. Por favor, explica qué hacen metaeditor.exe y terminal.exe.

El compilador es el mismo para ambas plataformas. Está en metaeditor.exe
 
Renat Fatkhullin:
El compilador para ambas plataformas es el mismo. Está en metaeditor.exe
¿Y el ejecutor, que comprueba el mismo dynamic_cast, en terminal.exe?
 
fxsaber:
¿Y el ejecutor, que comprueba el mismo dynamic_cast, en terminal.exe?
Por supuesto
 
Renat Fatkhullin:
Otra pregunta como esta
Razón de la queja: