Questions on OOP in MQL5 - page 79

 
Vladimir Simakov:

Not costly in this case. It is costly (per dereference dereference) to call virtual methods.

I didn't have time to scratch out the code, here is a method:

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

I can write it like this (call results are one-to-one - i.e. I have done everything correctly):

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

I call it like this:

JSONObject *jobj = getJSONObject(getStateIni());

i.e. variant 1 and variant 2 will be the same in speed? .... Of course, I'm confused by the length of the string in if() ... code is hard to read, maybe because of habituation

 
Igor Makanu:

I didn't have time to scratch out the code, here's a method:

I can write it like this (call results are one-to-one - i.e. I've done everything correctly):

I call it like this:

i.e. variant 1 and variant 2 will be the same in speed? .... Of course, I'm confused by the string length in if() ... ... code is hard to read, maybe from the firsthand experience.

If it is exactly the same without optimization by the compiler, the second is faster. The jo-pointer is not created and initialized.

PS.

(JSONObject *)jv

unnecessary. Just return jv

UPD: Is that shorter?
if (jv!=NULL && jv.isObject() && jv.getInt("ActorType") == (int)ActorType)
 
Vladimir Simakov:

UPD: Is it shorter?

JSONValue *jv does not contain getInt() , getDouble() methods - would be an error, need JSONObject type - or lead to that type

'getInt' - no one of the overloads can be applied to the function call

I don't want to cast it to int - I'm too lazy to write comments, I won't understand later what I was comparing, and the enum is only interesting, because it can be read with the eyes

Thank you!

 
Igor Makanu:

JSONValue *jv does not contain getInt() , getDouble() methods - there will be an error, JSONObject type is needed - or lead to that type

'getInt' - no one of the overloads can be applied to the function call

I don't want to cast it to int - I'm too lazy to write comments, I won't understand later what I was comparing, and the enum is only interesting, because it can be read with the eyes

Thank you!

Don't you have JSONValue:public JSONObject ?
 
Vladimir Simakov:
Don't you have JSONValue:public JSONObject ?

it doesn't work like this

the library is from githab, here are the source codehttps://www.mql5.com/ru/forum/85652/page72#comment_16758982

early version (so as not to download) in KBhttps://www.mql5.com/en/code/11134- there is also an example of how to use it

 
Igor Makanu:

it doesn't work like this

library is from githab, here are the source codehttps://www.mql5.com/ru/forum/85652/page72#comment_16758982

early version (so as not to download) in KBhttps://www.mql5.com/en/code/11134- there is also an example of use

Yeah... You have a UB here. You can't cast to an inheritor, but you kinda got around that by creating a pointer to the inheritor and assigning it the value of the correct pointer. That's fine, but as soon as
parser.parse(json)

it won't return JSONObject*, everything will fall into run-time)))))

Good for you))) You can NEVER cast directly from base to descendant - it's UB ( UNDEFINED BEHAVIOR), when you do that in pluses, nothing will drop, but... (there's a joke about being able to execute while doing so god bless the king))))

Right:

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

And the first person who starts telling you about the cost of dynamic_cast - nail the question, how does run-time know that cast is wrong?

 
Vladimir Simakov:
1) Yup... You have a UB here. You can't cast to an inheritor, but you kinda got around that by creating a pointer to the inheritor and assigning it the value of the correct pointer.
It's OK, but as soon as it returns a non JSONObject*, everything will fall into run-time)))

And you deserve it)))) NEVER directly cast from base to heir is UB ( UNDEFINED BEHAVIOR), when you do that in pluses nothing will fall, but... (there's a joke, about the possibility of execution at that God save the king

2) Right: And the first one who starts telling you about the cost of dynamic_cast - nail him with a question, how does run-time know that the cast is wrong?

1) There is no UB and nothing will drop even when a non JSONObject* is returned, because the real object type is checked viajv.isObject() method, which is exactly what you don't use.
2) It is your example that may become unworkable if the next version of the library introduces a new data type that usesJSONObject as a base class.

 
Sergey Dzyublik:

1) There is no UB and nothing will crash even when JSONObject* is not returned, because the real object type is checked viajv.isObject() method, which is exactly what you don't use.
2) It is your example that may become unworkable if the next version of the library introduces a new data type that usesJSONObject as a base class.

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

Highlighted. Check only on the next line))) In the lib creator's example, just the opposite, first check, then cast)

UPD: dynamic_cast works both ways)

UPD2: if JSONObject has an heir, why should that drop?

 
Vladimir Simakov:
Yeah... You have UB here.
There is no UB, mql cast includes also dynamic_cast. just everything will fall down in case of wrong pointer.
 
Andrei Trukhanovich:
There is no UB, mql cast includes also dynamic_cast. just everything will fall down in case of wrong pointer.

I agree))) That's me on the plus side.))

Reason: