Fragen zu OOP in MQL5 - Seite 79

 
Vladimir Simakov:

Das ist in diesem Fall nicht kostspielig. Der Aufruf virtueller Methoden ist kostspielig (pro Dereferenz-Dereferenz).

Ich hatte keine Zeit, den Code auszukratzen, hier ist eine Methode:

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

Ich kann es so schreiben (die Anrufergebnisse sind eins-zu-eins - d.h. ich habe alles richtig gemacht):

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

Ich nenne es so:

JSONObject *jobj = getJSONObject(getStateIni());

d.h. Variante 1 und Variante 2 werden die gleiche Geschwindigkeit haben? .... Natürlich verwirrt mich die Stringlänge in if() ... der Code ist schwer zu lesen, vielleicht wegen der Gewöhnung

 
Igor Makanu:

Ich hatte keine Zeit, den Code auszukratzen, hier ist eine Methode:

Ich kann es so schreiben (die Anrufergebnisse sind eins-zu-eins - d.h. ich habe alles richtig gemacht):

Ich nenne es so:

d.h. Variante 1 und Variante 2 werden die gleiche Geschwindigkeit haben? .... Natürlich verwirrt mich die Stringlänge in if() ... .. .der Code ist schwer zu lesen, vielleicht aufgrund der Erfahrungen aus erster Hand.

Wenn es ohne Optimierung durch den Compiler genau dasselbe ist, ist der zweite schneller. Der Jo-Zeiger wird nicht erstellt und initialisiert.

PS.

(JSONObject *)jv

unnötig. Geben Sie einfach jv zurück

UPD: Ist das kürzer?
if (jv!=NULL && jv.isObject() && jv.getInt("ActorType") == (int)ActorType)
 
Vladimir Simakov:

UPD: Ist sie kürzer?

JSONValue *jv enthält keine getInt() , getDouble()-Methoden - wäre ein Fehler, benötigt JSONObject-Typ - oder führt zu diesem Typ

'getInt' - keine der Überladungen kann auf den Funktionsaufruf angewendet werden

Ich möchte es nicht in int umwandeln - ich bin zu faul, um Kommentare zu schreiben, ich werde später nicht verstehen, was ich verglichen habe, und das enum ist nur interessant, weil es mit den Augen gelesen werden kann

Ich danke Ihnen!

 
Igor Makanu:

JSONValue *jv enthält keine getInt() , getDouble() Methoden - es wird ein Fehler auftreten, JSONObject Typ wird benötigt - oder zu diesem Typ führen

'getInt' - keine der Überladungen kann auf den Funktionsaufruf angewendet werden

Ich möchte es nicht in int umwandeln - ich bin zu faul, um Kommentare zu schreiben, ich werde später nicht verstehen, was ich verglichen habe, und das enum ist nur interessant, weil es mit den Augen gelesen werden kann

Ich danke Ihnen!

Haben Sie nicht JSONValue:public JSONObject ?
 
Vladimir Simakov:
Haben Sie nicht JSONValue:public JSONObject ?

So funktioniert es nicht

die Bibliothek ist von githab, hier sind die Quelltextehttps://www.mql5.com/ru/forum/85652/page72#comment_16758982

frühe Version (damit sie nicht heruntergeladen werden muss) in KBhttps://www.mql5.com/en/code/11134- dort gibt es auch ein Anwendungsbeispiel

 
Igor Makanu:

So funktioniert es nicht

Bibliothek ist von githab, hier sind die Quelltextehttps://www.mql5.com/ru/forum/85652/page72#comment_16758982

frühe Version (um nicht herunterzuladen) in KBhttps://www.mql5.com/en/code/11134- dort gibt es auch ein Beispiel für die Verwendung

Ja... Sie haben hier eine UB. Sie können nicht auf einen Erben casten, aber Sie haben das irgendwie umgangen, indem Sie einen Zeiger auf den Erben erstellt und ihm den Wert des richtigen Zeigers zugewiesen haben. Das ist in Ordnung, aber sobald
parser.parse(json)

es wird kein JSONObject* zurückgegeben, alles fällt in run-time)))))

Gut für Sie))) Sie können NIEMALS direkt von der Basis auf den Nachkommen werfen - es ist UB ( UNDEFINED BEHAVIOR), wenn Sie das in Plus tun, wird nichts fallen, aber... (es gibt einen Witz darüber, dass man dabei exekutieren kann, Gott segne den König))))

Richtig:

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

Und die erste Person, die Sie über die Kosten der dynamic_cast - Nagel die Frage, woher weiß die Laufzeit, dass cast ist falsch?

 
Vladimir Simakov:
1) Jep... Sie haben hier eine UB. Sie können nicht auf einen Erben casten, aber Sie haben das irgendwie umgangen, indem Sie einen Zeiger auf den Erben erstellt und ihm den Wert des richtigen Zeigers zugewiesen haben.
Es ist OK, aber sobald es ein Nicht-JSONObject* zurückgibt, wird alles in die Laufzeit fallen)))

Und du hast es verdient)))) NIEMALS direkt von der Basis auf den Erben zu werfen ist UB ( UNDEFINIERTES VERHALTEN), wenn man das im Plus macht, fällt nichts, aber... (es gibt einen Witz über die Möglichkeit der Hinrichtung bei diesem God save the king

2) Richtig: Und der erste, der anfängt, Ihnen von den Kosten von dynamic_cast zu erzählen - nageln Sie ihn mit der Frage fest, woher die Laufzeit weiß, dass cast falsch ist?

1) Es gibt keine UB und es wird auch nichts fallen gelassen, wenn ein Nicht-JSONObject* zurückgegeben wird, da der tatsächliche Objekttyp über die Methodejv.isObject() überprüft wird, was genau das ist, was Sie nicht verwenden.
2) Es ist Ihr Beispiel, das möglicherweise nicht mehr funktioniert, wenn die nächste Version der Bibliothek einen neuen Datentyp einführt, derJSONObject als Basisklasse verwendet.

 
Sergey Dzyublik:

1) Es gibt keine UB und nichts stürzt ab, selbst wenn JSONObject* zurückgegeben wird, da der tatsächliche Objekttyp über die Methodejv.isObject() überprüft wird, was genau das ist, was Sie nicht verwenden.
2) Es ist Ihr Beispiel, das möglicherweise nicht mehr funktioniert, wenn die nächste Version der Bibliothek einen neuen Datentyp einführt, derJSONObject als Basisklasse verwendet.

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

Hervorgehoben. Nur in der nächsten Zeile prüfen))) Im Beispiel des Lib-Erstellers ist es genau umgekehrt: erst prüfen, dann werfen)

UPD: dynamic_cast funktioniert in beide Richtungen)

UPD2: Wenn JSONObject einen Erben hat, warum sollte dieser fallen?

 
Vladimir Simakov:
Ja... Sie haben UB hier.
Es gibt keine UB, mql cast umfasst auch dynamic_cast. nur alles wird im Falle der falschen Zeiger fallen.
 
Andrei Trukhanovich:
Es gibt keine UB, mql cast umfasst auch dynamic_cast. nur alles wird im Falle der falschen Zeiger fallen.

Ich stimme zu))) Das bin ich auf der positiven Seite).