Erros, bugs, perguntas - página 1891

 
Renat Fatkhullin:

Claro.

Tem a certeza? Porque o dynamic_cast é mais frequentemente utilizado para conversão de baixo para cima, de pai para filho.

Além disso, em MQL ele funde perfeitamente de baixo para cima, mesmo quando não deveria:

class A
{
public:
   virtual void f()
   {
      Print("1");
   }
};

class B: public A
{
public:
   virtual void f()
   {
      Print("2");
   }
};

void OnStart()
{
   A* ptr1 = new B();
   ptr1.f();
   A* ptr2 = new A();
   ptr2.f();
   
   B* casted = dynamic_cast<B*>(ptr1);
   casted.f();
   
   B* casted1 = dynamic_cast<B*>(ptr2);
   casted1.f(); // здесь должна быть ошибка потому что casted1 должен быть null
   delete ptr1;
   delete ptr2;
}

вывод:
2017.05.13 18:30:14.864    t ETHUSD,M5: 2
2017.05.13 18:30:14.865    t ETHUSD,M5: 1
2017.05.13 18:30:14.866    t ETHUSD,M5: 2
2017.05.13 18:30:14.867    t ETHUSD,M5: 2


Renat Fatkhullin:

Dê uma vista de olhos ao fragmento de código MQL5 discutido.

Sim, não deve funcionar e já está explicado acima, mas não porque o gesso de baixo para cima é impossível.

 
Konstantin:
Se lançarmos o ponteiro de cima para baixo, isto é, para o pai, após o que passamos o ponteiro para outro lugar no âmbito, os campos do descendente estarão lá disponíveis?

Sim, aqui está um exemplo que demonstra a sua pergunta:

class CLASS1
  {
public:
   int               i;
  };
class CLASS2 : public CLASS1
  {
  };
void OnStart()
  {
   CLASS1 _object;
   CLASS2 *_ptr=dynamic_cast<CLASS2 *>(&_object);

   if(!_ptr)
      Print("CLASS1 -> CLASS2 failed, null");

   CLASS2 *my=new CLASS2;
   CLASS1 *my_ptr=my;
   CLASS2 *my_ptr2=dynamic_cast<CLASS2 *>(my_ptr);

   if(my_ptr2)
     {
      Print("CLASS2 -> CLASS1 -> CLASS2 ok");
      my_ptr2.i=1;
     }
   Print("Value: ",my.i);
  }
e produção:
2017.05.13 18:34:50.341 cast (EURUSD,H1)        CLASS1 -> CLASS2 failed, null
2017.05.13 18:35:18.933 cast (EURUSD,H1)        CLASS2 -> CLASS1 -> CLASS2 ok
2017.05.13 18:35:20.110 cast (EURUSD,H1)        Value: 1

Primeiro, verificamos o elenco não resolvido de baixo para cima e obtemos o NULL. Isto é correcto.

Depois criamos um objecto da CLASS2, atribuímos-lhe uma referência à sua classe mãe (aqui é importante compreender que dinamicamente o ambiente sabe que o tipo original do objecto da CLASS2 é armazenado na sua meta-informação). Em seguida (apenas a sua pergunta), fundido dinamicamente (com verificação do direito de conversão com base na metainformação do objecto fonte) da referência CLASSE1 para a CLASSE2.

Verificamos o resultado da fundição e escrevemo-lo na variável i = 1. Finalmente, produzimos o valor de i, referenciando o objecto originalmente criado.

Tudo funciona correctamente e de acordo com a especificação (incluindo a especificação dinâmica_cast do próprio C++).

 
Комбинатор:

Tem a certeza? Porque o dynamic_cast é mais frequentemente utilizado para conversão de baixo para cima, de pai para filho.

Além disso, em MQL ele funde perfeitamente de baixo para cima, mesmo quando não deveria:

Exactamente:

Não se esqueça de se actualizar para as últimas construções. Estou actualmente a testar em 1598, que foi recentemente afixado como fechos de correr neste tópico, penso eu.

 
Renat Fatkhullin:

Não se esqueça de se actualizar para as últimas construções.

Sim, a velha construção.

Renat Fatkhullin:

É verdade, não se pode conduzir de baixo para cima, apenas de cima para baixo. Isto é por uma questão de segurança.

Deve limpar este, é enganador e contradiz directamente o funcionamento do dynamic_cast
 
Комбинатор:

Sim, a velha construção.

Se esfregar esta, é enganador e contradiz directamente o funcionamento do dynamic_cast

Como parte da CLASSE1 -> CLASSE2 exemplo de fundição cabeça a cabeça levantada, acertou. Este é o tipo de fundição que as pessoas têm a maior parte do tempo nas suas cabeças.

Além disso, é o "não se pode lançar de baixo para cima, apenas de cima para baixo" que está no centro da verificação de segurança do dynamic_cast.

Quem sabe o que está a fazer compreende a essência do dynamic_cast.

 
Renat Fatkhullin:

Não se esqueça de se actualizar para as últimas construções. Estou actualmente a testar em 1598, o que foi recentemente publicado como um fecho neste tópico, penso eu.

Em que ficheiro exe é que o compilador e o executor se encontram?

Neste momento o MT4b1080 está a executar o MEb1599. Por favor explique o que o metaeditor.exe e o terminal.exe fazem.

 
fxsaber:

Em que ficheiro exe é que o compilador e o executor se encontram?

O MT4b1080 está agora a executar o MEb1599. Por favor explique o que o metaeditor.exe e o terminal.exe fazem.

O compilador é o mesmo para ambas as plataformas. Está em metaeditor.exe
 
Renat Fatkhullin:
O compilador para ambas as plataformas é o mesmo. Está em metaeditor.exe
E o executor, que verifica o mesmo dynamic_cast, em terminal.exe ?
 
fxsaber:
E o executor, que verifica o mesmo dynamic_cast, em terminal.exe ?
É claro
 
Renat Fatkhullin:
Outra questão como esta