Preguntas sobre POO en MQL5 - página 79

 
Vladimir Simakov:

No es costoso en este caso. Es costoso (por dereferencia) llamar a métodos virtuales.

No he tenido tiempo de rascar el código, aquí hay un método:

JSONObject * CActor::getJSONObject(const string json)const
{
   JSONParser parser;
   JSONValue  *jv;
   JSONObject *jo = jv = parser.parse(json);
   if (jv != NULL && jv.isObject() && (EACTOR_TYPE)jo.getInt("ActorType") == ActorType) return(jo);
   Print(__FUNCTION__ + "parser error, json = ",json);
   delete jv;
   delete jo;
   return(NULL);
}

Puedo escribirlo así (los resultados de las llamadas son uno a uno, es decir, he hecho todo correctamente):

JSONObject * CActor::getJSONObject(const string json)const
{
   JSONParser parser;
   JSONValue  *jv = parser.parse(json);
   //JSONObject *jo = jv = parser.parse(json);
   if (jv != NULL && jv.isObject() && (EACTOR_TYPE)(((JSONObject *)jv).getInt("ActorType")) == ActorType) return((JSONObject *)jv);
   Print(__FUNCTION__ + "parser error, json = ",json);
   delete jv;
   return(NULL);
}

Yo lo llamo así:

JSONObject *jobj = getJSONObject(getStateIni());

es decir, ¿la variante 1 y la variante 2 tendrán la misma velocidad? .... Por supuesto, me confunde la longitud de la cadena en if() ... el código es difícil de leer, tal vez debido a la habituación

 
Igor Makanu:

No he tenido tiempo de rascar el código, aquí hay un método:

Puedo escribirlo así (los resultados de las llamadas son uno a uno, es decir, he hecho todo correctamente):

Yo lo llamo así:

es decir, ¿la variante 1 y la variante 2 tendrán la misma velocidad? .... Por supuesto, me confunde la longitud de la cadena en if() ... .. .el código es difícil de leer, tal vez por la experiencia de primera mano.

Si es exactamente lo mismo sin la optimización del compilador, el segundo es más rápido. El jo-pointer no se crea ni se inicializa.

PS.

(JSONObject *)jv

innecesario. Sólo hay que devolver jv

UPD: ¿Es más corto?
if (jv!=NULL && jv.isObject() && jv.getInt("ActorType") == (int)ActorType)
 
Vladimir Simakov:

UPD: ¿Es más corto?

JSONValue *jv no contiene los métodos getInt() , getDouble() - sería un error, necesita el tipo JSONObject - o llevar a ese tipo

'getInt' - no se puede aplicar ninguna de las sobrecargas a la llamada de la función

No quiero lanzarlo a int - me da pereza escribir comentarios, no entenderé después lo que estaba comparando, y el enum sólo es interesante, porque se puede leer con los ojos

Gracias.

 
Igor Makanu:

JSONValue *jv no contiene los métodos getInt() , getDouble() - habrá un error, se necesita el tipo JSONObject - o llevar a ese tipo

'getInt' - no se puede aplicar ninguna de las sobrecargas a la llamada de la función

No quiero lanzarlo a int - me da pereza escribir comentarios, no entenderé después lo que estaba comparando, y el enum sólo es interesante, porque se puede leer con los ojos

Gracias.

¿No tiene JSONValue:public JSONObject ?
 
Vladimir Simakov:
¿No tiene JSONValue:public JSONObject ?

no funciona así

La biblioteca es de github, aquí está el código fuentehttps://www.mql5.com/ru/forum/85652/page72#comment_16758982

versión temprana (para no descargarla) en KBhttps://www.mql5.com/en/code/11134- también hay un ejemplo de cómo utilizarla

 
Igor Makanu:

no funciona así

La biblioteca es de githab, aquí está el código fuentehttps://www.mql5.com/ru/forum/85652/page72#comment_16758982

versión temprana (para no descargar) en KBhttps://www.mql5.com/en/code/11134- también hay un ejemplo de uso

Sí... Tienes un UB aquí. No se puede hacer un casting a un heredero, pero se puede evitar creando un puntero al heredero y asignándole el valor del puntero correcto. Eso está bien, pero tan pronto como
parser.parse(json)

no devolverá JSONObject*, todo caerá en run-time)))))

Bien por ti)) NUNCA puedes lanzar directamente de base a descendiente - es UB ( UNDEFINED BEHAVIOR), cuando haces eso en los pluses, no caerá nada, pero... (hay un chiste sobre ser capaz de ejecutar mientras se hace así Dios bendiga al rey))))

Sí:

JSONObject* jv = dynamic_cast<JSONObject*>(parser.parse(json));
if (jv != NULL && jv.getInt("ActorType") == ActorType) return jv;

Y la primera persona que empiece a hablarte del coste de dynamic_cast - clava la pregunta, ¿cómo sabe el tiempo de ejecución que el cast está mal?

 
Vladimir Simakov:
1) Sí... Tienes un UB aquí. No se puede hacer un casting a un heredero, pero se puede evitar creando un puntero al heredero y asignándole el valor del puntero correcto.
Está bien, pero en cuanto devuelva un objeto no JSONObject*, todo caerá en tiempo de ejecución))

Y te lo mereces)))) NUNCA lanzar directamente de la base al heredero es UB ( UNDEFINED BEHAVIOR), cuando haces eso en los pluses no caerá nada, pero... (hay un chiste, sobre la posibilidad de ejecución en ese Dios salve al rey

2) Correcto: Y el primero que empiece a hablarte del coste de dynamic_cast - clávalo con una pregunta, ¿cómo sabe el tiempo de ejecución que el cast está mal?

1) No hay UB y nada caerá incluso cuando se devuelva un objeto que no sea JSONObject*, porque el tipo de objeto real se comprueba a través del métodojv.isObject(), que es exactamente lo que no se utiliza.
2) Es tu ejemplo el que puede resultar inviable si la próxima versión de la biblioteca introduce un nuevo tipo de datos que utiliceJSONObject como clase base.

 
Sergey Dzyublik:

1) No hay ningún UB y nada se bloqueará incluso cuando no se devuelva JSONObject*, porque el tipo de objeto real se comprueba a través del métodojv.isObject(), que es exactamente lo que no se utiliza.
2) Es tu ejemplo el que puede resultar inviable si la próxima versión de la biblioteca introduce un nuevo tipo de datos que utiliceJSONObject como clase base.

JSONObject * CActor::getJSONObject(const string json)const
{
   JSONParser parser;
   JSONValue  *jv;
   JSONObject *jo = jv = parser.parse(json);
   if (jv != NULL && jv.isObject() && (EACTOR_TYPE)jo.getInt("ActorType") == ActorType) return(jo);
   Print(__FUNCTION__ + "parser error, json = ",json);
   delete jv;
   delete jo;
   return(NULL);
}

Destacado. Compruebe sólo en la línea siguiente)) En el ejemplo del creador de la librería, justo lo contrario, primero se comprueba y luego se lanza)

UPD: dynamic_cast funciona en ambos sentidos)

UPD2: si JSONObject tiene un heredero, ¿por qué debería caer?

 
Vladimir Simakov:
Sí... Tienes a UB aquí.
No hay UB, mql cast incluye también dynamic_cast. simplemente todo se caerá en caso de puntero equivocado.
 
Andrei Trukhanovich:
No hay UB, mql cast incluye también dynamic_cast. simplemente todo se caerá en caso de puntero equivocado.

Estoy de acuerdo))) Ese soy yo en el lado positivo)).