Perguntas sobre OOP em MQL5 - página 79

 
Vladimir Simakov:

Neste caso, não custa caro. É caro (por desreferenciamento) chamar métodos virtuais.

Não tive tempo de riscar o código, aqui está um 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);
}

Posso escrevê-lo assim (os resultados da chamada são um-para-um - ou seja, fiz tudo corretamente):

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

Eu o chamo assim:

JSONObject *jobj = getJSONObject(getStateIni());

ou seja, a variante 1 e a variante 2 serão as mesmas em velocidade? .... É claro que estou confuso com o comprimento da corda no if() ... o código é difícil de ler, talvez por causa do hábito

 
Igor Makanu:

Não tive tempo de riscar o código, aqui está um método:

Posso escrevê-lo assim (os resultados da chamada são um-para-um - ou seja, fiz tudo corretamente):

Eu o chamo assim:

ou seja, a variante 1 e a variante 2 serão as mesmas em velocidade? .... É claro que estou confuso com o comprimento da corda no if() ... .. .o código é difícil de ler, talvez a partir da experiência em primeira mão.

Se for exatamente o mesmo sem otimização pelo compilador, o segundo é mais rápido. O jo-pointer não é criado e inicializado.

PS.

(JSONObject *)jv

desnecessária. Basta devolver jv

UPD: Isso é mais curto?
if (jv!=NULL && jv.isObject() && jv.getInt("ActorType") == (int)ActorType)
 
Vladimir Simakov:

UPD: É mais curto?

JSONValue *jv não contém métodos getInt() , getDouble() - seria um erro, precisaria do tipo JSONObject - ou levaria a esse tipo

getInt' - nenhuma das sobrecargas pode ser aplicada à chamada de função

Não quero fazer uma intriga - sou preguiçoso demais para escrever comentários, não vou entender mais tarde o que estava comparando, e o enumeral é apenas interessante, porque pode ser lido com os olhos

Obrigado!

 
Igor Makanu:

JSONValue *jv não contém métodos getInt() , getDouble() - haverá um erro, o tipo JSONObject é necessário - ou levar a esse tipo

getInt' - nenhuma das sobrecargas pode ser aplicada à chamada de função

Não quero fazer uma intriga - sou preguiçoso demais para escrever comentários, não vou entender mais tarde o que estava comparando, e o enumeral é apenas interessante, porque pode ser lido com os olhos

Obrigado!

Você não tem valor JSONValue:público JSONObject ?
 
Vladimir Simakov:
Você não tem valor JSONValue:público JSONObject ?

não funciona assim

A biblioteca é do github, aqui está o código fontehttps://www.mql5.com/ru/forum/85652/page72#comment_16758982

versão inicial (para não baixar) em KBhttps://www.mql5.com/en/code/11134- há também um exemplo de como utilizá-la

 
Igor Makanu:

não funciona assim

A biblioteca é do githab, aqui está o código fontehttps://www.mql5.com/ru/forum/85652/page72#comment_16758982

versão inicial (para não baixar) em KBhttps://www.mql5.com/en/code/11134- há também um exemplo de uso

Sim... Você tem uma UB aqui. Você não pode lançar para um herdeiro, mas você meio que conseguiu contornar isso criando um ponteiro para o herdeiro e atribuindo a ele o valor do ponteiro correto. Tudo bem, mas assim que
parser.parse(json)

não retornará JSONObject*, tudo cairá em run-time)))))

Bom para você)))) Você NUNCA pode lançar diretamente da base para o descendente - é UB ( UNDEFINED BEHAVIOR), quando você faz isso em plenos pulsos, nada vai cair, mas... (há uma piada sobre ser capaz de executar enquanto o faz Deus abençoe o rei))))

Certo:

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

E a primeira pessoa que começa a lhe falar sobre o custo do dynamic_cast - pregue a pergunta, como saber se o elenco está errado no tempo de execução?

 
Vladimir Simakov:
1) Yup... Você tem uma UB aqui. Você não pode lançar para um herdeiro, mas você meio que conseguiu contornar isso criando um ponteiro para o herdeiro e atribuindo a ele o valor do ponteiro correto.
Está tudo bem, mas assim que retornar um não JSONObject*, tudo cairá em tempo de execução))))

E você merece)))) NUNCA se lança diretamente da base para o herdeiro é a UB ( UNDEFINED BEHAVIOR), quando se faz isso em plenos pulsos nada vai cair, mas... (há uma piada, sobre a possibilidade de execução naquele Deus que salva o rei

2) Certo: E o primeiro que começa a falar sobre o custo do dynamic_cast - pregá-lo com uma pergunta, como o run-time sabe que o elenco está errado?

1) Não há UB e nada vai cair mesmo quando um objeto não JSONObject* for devolvido, porque o tipo de objeto real é verificado através do métodojv.isObject(), que é exatamente o que você não usa.
2) É seu exemplo que pode se tornar impraticável se a próxima versão da biblioteca introduzir um novo tipo de dados que useo JSONObject como classe base.

 
Sergey Dzyublik:

1) Não há UB e nada se chocará mesmo quando o JSONObject* não for devolvido, porque o tipo de objeto real é verificado através do métodojv.isObject(), que é exatamente o que você não usa.
2) É seu exemplo que pode se tornar impraticável se a próxima versão da biblioteca introduzir um novo tipo de dados que useo JSONObject como 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);
}

Em destaque. Verifique apenas na linha seguinte)))) No exemplo do criador da libra, exatamente o oposto, primeiro cheque, depois elenco)

UPD: dynamic_cast funciona nos dois sentidos)

UPD2: se o JSONObject tem um herdeiro, por que isso deveria cair?

 
Vladimir Simakov:
Sim... Você tem aqui a UB.
Não há UB, o elenco mql inclui também Dynamic_cast. apenas tudo cairá em caso de ponteiro errado.
 
Andrei Trukhanovich:
Não há UB, o elenco mql inclui também Dynamic_cast. apenas tudo cairá em caso de ponteiro errado.

Eu concordo)))) Esse sou eu no lado positivo)).

Razão: