Questions sur la POO dans MQL5 - page 79

 
Vladimir Simakov:

Pas coûteux dans ce cas. Il est coûteux (par déréférencement) d'appeler des méthodes virtuelles.

Je n'ai pas eu le temps de gratter le code, voici une méthode :

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

Je peux l'écrire comme ceci (les résultats des appels sont univoques - c'est-à-dire que j'ai tout fait correctement) :

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

Je l'appelle comme ça :

JSONObject *jobj = getJSONObject(getStateIni());

c'est-à-dire que la variante 1 et la variante 2 auront la même vitesse ? .... Bien sûr, je suis confus par la longueur de la chaîne dans if() ... le code est difficile à lire, peut-être à cause de l'accoutumance

 
Igor Makanu:

Je n'ai pas eu le temps de gratter le code, voici une méthode :

Je peux l'écrire comme ceci (les résultats des appels sont univoques - c'est-à-dire que j'ai tout fait correctement) :

Je l'appelle comme ça :

c'est-à-dire que la variante 1 et la variante 2 auront la même vitesse ? .... Bien sûr, je suis confus par la longueur de la chaîne dans if() ... .. .le code est difficile à lire, peut-être à cause de l'expérience de première main.

Si c'est exactement la même chose sans optimisation par le compilateur, la seconde est plus rapide. Le jo-pointeur n'est pas créé et initialisé.

PS.

(JSONObject *)jv

inutile. Retournez simplement jv

UPD : C'est plus court ?
if (jv!=NULL && jv.isObject() && jv.getInt("ActorType") == (int)ActorType)
 
Vladimir Simakov:

UPD : C'est plus court ?

JSONValue *jv ne contient pas les méthodes getInt() , getDouble() - ce serait une erreur, il faut un type JSONObject - ou conduire vers ce type

getInt' - aucune des surcharges ne peut être appliquée à l'appel de fonction.

Je ne veux pas le convertir en int - je suis trop paresseux pour écrire des commentaires, je ne comprendrai pas plus tard ce que je comparais, et l'énumération n'est intéressante que parce qu'elle peut être lue avec les yeux.

Merci !

 
Igor Makanu:

JSONValue *jv ne contient pas les méthodes getInt() , getDouble() - il y aura une erreur, le type JSONObject est nécessaire - ou mène à ce type

getInt' - aucune des surcharges ne peut être appliquée à l'appel de fonction.

Je ne veux pas le convertir en int - je suis trop paresseux pour écrire des commentaires, je ne comprendrai pas plus tard ce que je comparais, et l'énumération n'est intéressante que parce qu'elle peut être lue avec les yeux.

Merci !

N'avez-vous pas JSONValue:public JSONObject ?
 
Vladimir Simakov:
N'avez-vous pas JSONValue:public JSONObject ?

ça ne fonctionne pas comme ça

la bibliothèque vient de githab, voici le code sourcehttps://www.mql5.com/ru/forum/85652/page72#comment_16758982

version anticipée (afin de ne pas la télécharger) dans KBhttps://www.mql5.com/en/code/11134- il y a aussi un exemple d'utilisation de ce logiciel

 
Igor Makanu:

ça ne fonctionne pas comme ça

La bibliothèque est issue de githab, voici le code sourcehttps://www.mql5.com/ru/forum/85652/page72#comment_16758982

version anticipée (afin de ne pas la télécharger) dans KBhttps://www.mql5.com/en/code/11134- il y a aussi un exemple d'utilisation

Ouais... Vous avez une UB ici. Vous ne pouvez pas effectuer de cast vers un héritier, mais vous avez contourné ce problème en créant un pointeur vers l'héritier et en lui attribuant la valeur du pointeur correct. C'est bon, mais dès que
parser.parse(json)

il ne retournera pas JSONObject*, tout tombera dans run-time)))))

C'est bien pour vous)))) Vous ne pouvez JAMAIS lancer directement de la base au descendant - c'est UB ( UNDEFINED BEHAVIOR), quand vous faites cela dans les plus, rien ne tombera, mais... (il y a une blague sur le fait d'être capable d'exécuter tout en le faisant, Dieu bénisse le roi)))).

Bien :

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

Et la première personne qui commence à vous parler du coût du dynamic_cast - cloue la question, comment le run-time sait-il que le cast est mauvais ?

 
Vladimir Simakov:
1) Ouaip... Vous avez une UB ici. Il n'est pas possible d'effectuer un casting vers un héritier, mais vous avez contourné ce problème en créant un pointeur vers l'héritier et en lui attribuant la valeur du pointeur correct.
C'est OK, mais dès qu'il renvoie un non JSONObject*, tout tombera à l'eau))).

Et tu le mérites)))) Ne JAMAIS lancer directement de la base à l'héritier est UB ( UNDEFINED BEHAVIOR), quand vous faites ça dans les plus rien ne tombera, mais... (il y a une blague, sur la possibilité d'exécution à ce God save the king

2) Bien : Et le premier qui commence à vous parler du coût du dynamic_cast - clouez-le avec une question, comment le run-time sait-il que le cast est faux ?

1) Il n'y a pas d'UB et rien ne tombera même si un non JSONObject* est retourné, car le type réel de l'objet est vérifié via la méthodejv.isObject(), qui est exactement ce que vous n'utilisez pas.
2) C'est votre exemple qui peut devenir inapplicable si la prochaine version de la bibliothèque introduit un nouveau type de données qui utiliseJSONObject comme classe de base.

 
Sergey Dzyublik:

1) Il n'y a pas d'UB et rien ne plantera même si JSONObject* n'est pas retourné, car le type réel de l'objet est vérifié via la méthodejv.isObject(), qui est exactement ce que vous n'utilisez pas.
2) C'est votre exemple qui peut devenir inapplicable si la prochaine version de la bibliothèque introduit un nouveau type de données qui utiliseJSONObject comme classe de 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);
}

Mis en évidence. Vérifiez seulement sur la ligne suivante))) Dans l'exemple du créateur de la librairie, c'est exactement le contraire, il faut d'abord vérifier, puis lancer).

UPD : dynamic_cast fonctionne dans les deux sens)

UPD2 : si JSONObject a un héritier, pourquoi cela devrait-il tomber ?

 
Vladimir Simakov:
Ouais... Vous avez l'UB ici.
Il n'y a pas d'UB, le mql cast inclut aussi le dynamic_cast. Tout tombera en cas de mauvais pointeur.
 
Andrei Trukhanovich:
Il n'y a pas d'UB, le mql cast inclut aussi le dynamic_cast. Tout tombera en cas de mauvais pointeur.

Je suis d'accord))) C'est moi du côté positif.))