Domande su OOP in MQL5 - pagina 79

 
Vladimir Simakov:

Non è costoso in questo caso. È costoso (per dereferenza) chiamare metodi virtuali.

Non ho avuto il tempo di grattare il codice, ecco un metodo:

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

Posso scriverlo così (i risultati delle chiamate sono uno a uno - cioè ho fatto tutto correttamente):

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

Io lo chiamo così:

JSONObject *jobj = getJSONObject(getStateIni());

cioè la variante 1 e la variante 2 avranno la stessa velocità? .... Naturalmente, sono confuso dalla lunghezza della stringa in if() ... il codice è difficile da leggere, forse a causa dell'assuefazione

 
Igor Makanu:

Non ho avuto tempo di grattare il codice, ecco un metodo:

Posso scriverlo così (i risultati delle chiamate sono uno a uno - cioè ho fatto tutto correttamente):

Io lo chiamo così:

cioè la variante 1 e la variante 2 avranno la stessa velocità? .... Naturalmente, sono confuso dalla lunghezza della stringa in if() ... .. .il codice è difficile da leggere, forse per l'esperienza diretta.

Se è esattamente lo stesso senza ottimizzazione da parte del compilatore, il secondo è più veloce. Il jo-pointer non viene creato e inizializzato.

PS.

(JSONObject *)jv

inutile. Basta restituire jv

UPD: è più corto?
if (jv!=NULL && jv.isObject() && jv.getInt("ActorType") == (int)ActorType)
 
Vladimir Simakov:

UPD: È più corto?

JSONValue *jv non contiene i metodi getInt() , getDouble() - sarebbe un errore, serve il tipo JSONObject - o porta a quel tipo

'getInt' - nessuno degli overload può essere applicato alla chiamata della funzione

Non voglio castarlo a int - sono troppo pigro per scrivere commenti, non capirò più tardi cosa stavo confrontando, e l'enum è interessante solo perché può essere letto con gli occhi

Grazie!

 
Igor Makanu:

JSONValue *jv non contiene i metodi getInt() , getDouble() - ci sarà un errore, è necessario il tipo JSONObject - o portare a quel tipo

'getInt' - nessuno degli overload può essere applicato alla chiamata di funzione

Non voglio castarlo a int - sono troppo pigro per scrivere commenti, non capirò più tardi cosa stavo confrontando, e l'enum è interessante solo perché può essere letto con gli occhi

Grazie!

Non hai JSONValue:public JSONObject?
 
Vladimir Simakov:
Non hai JSONValue:public JSONObject?

non funziona così

la libreria è da githab, ecco il codice sorgentehttps://www.mql5.com/ru/forum/85652/page72#comment_16758982

versione anticipata (per non scaricare) in KBhttps://www.mql5.com/en/code/11134- c'è anche un esempio di come usarlo

 
Igor Makanu:

non funziona così

la libreria è da githab, ecco il codice sorgentehttps://www.mql5.com/ru/forum/85652/page72#comment_16758982

versione anticipata (per non scaricare) in KBhttps://www.mql5.com/en/code/11134- c'è anche un esempio di utilizzo

Già... Qui avete un UB. Non puoi fare il cast su un erede, ma hai aggirato il problema creando un puntatore all'erede e assegnandogli il valore del puntatore corretto. Va bene, ma appena
parser.parse(json)

non restituirà JSONObject*, tutto cadrà in run-time)))))

Buon per te))) Non puoi MAI lanciare direttamente dalla base al discendente - è UB ( UNDEFINED BEHAVIOR), quando lo fai in più, non cade niente, ma... (c'è una battuta sull'essere in grado di eseguire mentre si fa così Dio benedica il re))))

Giusto:

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

E la prima persona che inizia a parlarvi del costo di dynamic_cast - inchioda la domanda, come fa run-time a sapere che il cast è sbagliato?

 
Vladimir Simakov:
1) Sì... Qui avete un UB. Non puoi fare il cast su un erede, ma hai aggirato il problema creando un puntatore all'erede e assegnandogli il valore del puntatore corretto.
Va bene, ma appena restituisce un non JSONObject*, tutto cadrà in run-time)))

E te lo meriti)))) Non lanciare mai direttamente dalla base all'erede è UB ( UNDEFINED BEHAVIOR), quando lo fai in più non cade nulla, ma... (c'è una battuta, sulla possibilità di esecuzione in quel God save the king

2) Giusto: e il primo che inizia a parlarvi del costo di dynamic_cast - inchiodatelo con una domanda, come fa run-time a sapere che il cast è sbagliato?

1) Non c'è nessun UB e nulla cadrà anche quando viene restituito un non JSONObject*, perché il vero tipo di oggetto viene controllato tramite il metodojv.isObject(), che è esattamente quello che non si usa.
2) È il tuo esempio che può diventare impraticabile se la prossima versione della libreria introduce un nuovo tipo di dati che usaJSONObject come classe base.

 
Sergey Dzyublik:

1) Non c'è nessun UB e non c'è nessun crash anche quando JSONObject* non viene restituito, perché il vero tipo di oggetto viene controllato tramite il metodojv.isObject(), che è esattamente quello che non si usa.
2) È il tuo esempio che può diventare impraticabile se la prossima versione della libreria introduce un nuovo tipo di dati che usaJSONObject come classe 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);
}

In evidenza. Controlla solo sulla linea successiva))) Nell'esempio del creatore di lib, proprio il contrario, prima controllare, poi lanciare)

UPD: dynamic_cast funziona in entrambi i modi)

UPD2: se JSONObject ha un erede, perché dovrebbe cadere?

 
Vladimir Simakov:
Già... Qui avete UB.
Non c'è nessun UB, mql cast include anche dynamic_cast. semplicemente tutto cadrà in caso di puntatore sbagliato.
 
Andrei Trukhanovich:
Non c'è nessun UB, mql cast include anche dynamic_cast. semplicemente tutto cadrà in caso di puntatore sbagliato.

Sono d'accordo))) Questo è il mio lato positivo)).