Errores, fallos, preguntas - página 2363

 
Igor Makanu:

¡typedef es un tema, lo intenté, pero no me fue bien, todavía tengo que averiguar donde me equivoqué, mi ejemplo debería funcionar con typedef también!

El código que escribí arriba debería funcionar. Quise comprobarlo yo mismo, pero no hubo suerte: =)))))))))))


(construcción 1961)

 
Igor Makanu:

¡typedef es un tema, lo intenté, pero no me fue bien, todavía tengo que averiguar donde me equivoqué, mi ejemplo debería funcionar con typedef también!

Pero se puede hacer más simple y elegante - sin paréntesis y punteros innecesarios - (y se compila sin errores extraños))))

#property strict

class CObject{ };
class CMyclass: public CObject {
  public: CMyclass *operator[] (CObject*p){ CMyclass*r = dynamic_cast<CMyclass*>(p); 
                                return CheckPointer(r)!=POINTER_INVALID?r:NULL; }
          int f(){ return 1; } 
} my ;

void OnStart()
{
  CObject*co=new CMyclass;
  
  my[co].f();
}
 
Ilya Malev:

¿Puedes hacerlo más simple y elegante - sin paréntesis y punteros innecesarios - (y que compile sin errores extraños))))

tu ejemplo no funcionará en mi caso, mis objetos se crean dinámicamente, ni siquiera les asigno un nombre, mientras que tu ejemplo utiliza un nombre de puntero, lo he intentado así, el compilador no deja pasar: '[' - nombre esperado tst_cast.mq4 32 15


#property strict
#include <Object.mqh>
#include <Arrays\List.mqh>
//+------------------------------------------------------------------+
class CMyclass:public CObject
  {
public:
   int               x;
   double            y;
   CObject           *obj;
   void              CMyclass(void):x(-1),y(-2.2)  {                       }
   public: CMyclass *operator[] (CObject*p){ CMyclass*r = dynamic_cast<CMyclass*>(p); 
                                             return CheckPointer(r)!=POINTER_INVALID?r:NULL; }         
  };
//+------------------------------------------------------------------+
void OnStart()
  {
   CList *base=new CList;
   for(int i=0;i<3;i++)
     {
      base.Add(new CMyclass);
      ((CMyclass*)base.GetCurrentNode()).x = 99;
      ((CMyclass*)base.GetCurrentNode()).y = 555;
      CMyclass[base.GetCurrentNode()].x = 111;
     }

   for(int i=0;i<3;i++)
     {
      Print(((CMyclass*)base.GetNodeAtIndex(i)).x," : ",((CMyclass*)base.GetNodeAtIndex(i)).y);
     }
   delete base;
  }
//+------------------------------------------------------------------+

SZZ: He empezado a entender un poco lo que sugieres, pero aún no hay resultado, puedo prescindir de dynamic_cast <>, añadir * campoCObject, en teoría debería ser así:

...
 CObject           *obj;
 CMyclass          *operator[](CObject*p)        { obj = p; return(obj); }          
  };

Creo que funcionará un poco más rápido que tu ejemplo con dynamic_cast <> - el significado es el mismo

 
Igor Makanu:

si es posible dereferir un puntero *CObject en MQL ?

He probado diferentes variantes, aquí hay un script de prueba, añado 3 elementos de Myclass a la lista enlazada y luego cambio los valores de los campos de CMyclass, funciona:

¿Puedo modificar campos de elementosCMyclass creados dinámicamente, sin puntero intermedioCMyclass *resultado?

Así:(CMyclass *)(base.GetCurrentNode()).x = 99;

PD: Sospecho que hay que usar typedef , pero hasta ahora no lo he conseguido

Lo que has escrito es sólo un uso implícito de la misma:

result=base.GetCurrentNode();

Es decir, tal puntero anónimo, pero esencialmente sólo azúcar sintáctico. Casi no hay azúcar en MQL, así que no se puede hacer así. Pero debo notar que el casting a descendiente se hace sin comprobaciones ni conversiones, así que no está claro por qué no te gusta el trabajo explícito con un puntero.

 
Igor Makanu:

ZS: un poco comenzó a entender lo que usted sugiere, pero todavía no hay resultado, se puede hacer sin dynamic_cast <>, añadir un campo * CObject , en teoría, debería ser así:

Creo que funcionará un poco más rápido que tu ejemplo con dynamic_cast <> - el significado es el mismo

Puede hacerlo sin un campo separado, como se sugiere arriba, pero sólo a través de la envoltura en el operador.

Hay una pequeña diferencia. Si de repente aparece un objeto no convertido a myclass, entonces sin dynamic_cast habrá un error de ejecución, y con él, obtendrá NULL a cambio. Si lo diriges con .x inmediatamente, causará un error de ejecución de todos modos, así que no te molestes =)))

Si hacemos lo que el doctor ordenó deberíamos devolver algo así como una instancia de clase especial creada para el manejo de errores ))))

P.D. He comprobado recientemente la velocidad de dynamic_casta, comparada con la del casting habitual - era casi la misma en caso de igualdad de clase con la esperada.

P.S.S. En cualquier caso, los for se ven bastante tristes ahí - cuando se trabaja con listas, se deben usar bucles como for each (como mi bucle)
 
Igor Makanu:

no pasa el compilador: '[' - nombre esperado tst_cast.mq4 32 15

#property strict
#include <Object.mqh>
#include <Arrays\List.mqh>
//+------------------------------------------------------------------+
class CMyclass:public CObject
  {
public:
   int               x;
   double            y;
   CObject           *obj;
   void              CMyclass(void):x(-1),y(-2.2)  {                       }
   public: CMyclass *operator[] (CObject*p){ CMyclass*r = dynamic_cast<CMyclass*>(p); 
                                             return CheckPointer(r)!=POINTER_INVALID?r:NULL; }         
  };
//+------------------------------------------------------------------+
void OnStart()
  {
   CList *base=new CList;
   for(int i=0;i<3;i++)
     {
      base.Add(new CMyclass);
      ((CMyclass*)base.GetCurrentNode()).x = 99;
      ((CMyclass*)base.GetCurrentNode()).y = 555;
      CMyclass[base.GetCurrentNode()].x = 111;
     }

   for(int i=0;i<3;i++)
     {
      Print(((CMyclass*)base.GetNodeAtIndex(i)).x," : ",((CMyclass*)base.GetNodeAtIndex(i)).y);
     }
   delete base;
  }
//+------------------------------------------------------------------+

...

¿Qué conseguimos realmente con esta envoltura? ¿Un dynamic_cast innecesario cuando es absolutamente innecesario? El propio wrapper tiene una conversión explícita a CMyClass. Es decir, tiene un 0% de carga de trabajo mientras que el código es más complicado (el operador de referencia al índice se utiliza como un operador de fundición explícito para la clase que se pasa - bueno, no es obvio en absoluto).

 
Ilya Malev:
P.S.S. En cualquier caso, los for se ven bastante tristes ahí - cuando se trabaja con listas, se deben usar bucles como for each (como mi bucle)

Lo siento, pero eso es una tontería.

 
Vasiliy Sokolov:

Lo que has escrito es sólo un uso implícito de la misma:

Es decir, un puntero anónimo de este tipo, pero básicamente sólo azúcar sintáctico. Casi no hay azúcar en MQL, por lo que no se puede hacer así. Pero debo señalar que el casting a descendiente se realiza sin comprobaciones ni conversiones, así que no está claro por qué el trabajo explícito con el puntero es tan molesto.

Sí, lo entiendo, sigo confundido con la sintaxis en MQL cuando se trabaja con punteros, parece lo mismo que en C++ estándar, pero me confundo constantemente y no puedo ni escribir algo directamente, ni leer el código de la biblioteca del paquete estándar MT.... correctamente ¡Me he tirado de los pelos! ... ¡pero aún en la ópera! )))) - De todos modos, lo resolveré ;)


Ilya Malev:

Hay una diferencia, una pequeña. Si resulta que hay un objeto no convertido a myclass, sin dynamic_cast habrá un error de ejecución, y con él se obtendrá simplemente NULL a cambio. Lo que de todas formas causará un error si se dirige con .x inmediatamente.

Entiendo todo esto, y no es una diferencia pequeña, diré sinceramente que el código de un programador profesional se diferencia de uno amateur en esta misma diferencia - en la comprobación de errores críticos ..... aunque con las tendencias modernas en los lenguajes de programación se ha simplificado para los programadores más lentos usando try excepto finally etc. ;)

 
Vasiliy Sokolov:

Lo siento, pero esto es una tontería.

Oh, por favor.

 
Igor Makanu:

Sí, lo entiendo todo, no consigo descifrar la sintaxis en MQL a la hora de trabajar con punteros, parece que es la misma que en C++ estándar, pero me confundo constantemente y no puedo ni escribir algo directamente, ni leer correctamente el código de la misma librería desde la entrega estándar de MT.... ¡Me he tirado de los pelos! ... ¡pero todavía en la .ópera! )))) - lo que se puede hacer es descubrirlo ;)

Tomar C++ como punto de referencia en el caso de MQL no funcionará :) El volumen de lo imposible en MQL es mucho mayor que el volumen de las construcciones "compatibles". En mi opinión, MQL se parece más a un C# muy truncado con una completa falta de azúcar sintáctico.