Erros, bugs, perguntas - página 1890

 
fxsaber:
Qual é o erro de execução

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

Não se pode comparar com C++ - qualquer coisa pode ser reduzida a qualquer coisa lá.

 
Комбинатор:
Em C++ também só funciona se um ponteiro para uma classe base apontar para o seu descendente.

Não sei o que quer dizer com isso, mas este código:

class CLASS1
{
public:
  int i;  
};

class CLASS2 : public CLASS1 {};

int main() {
  CLASS1 _object;
  CLASS2 *_ptr = (CLASS2*)&_object;  
  _ptr->i = 1;

   return 0;
}

trabalha em C++, que é o que escrevi acima. E aqui está o mesmo código (considerando a sintaxe MQL):

class CLASS1
{
public:
  int i;  
};

class CLASS2 : public CLASS1 {};

int OnInit() {
  CLASS1 _object;
  CLASS2 *_ptr = dynamic_cast<CLASS2 *>(&_object);
  
  _ptr.i = 1;

   return 0;
}
já não funciona porque _ptr recebe NULL
O que levanta a questão, será um erro no MQL e será corrigido ou ficará assim?
 
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.

Não se pode comparar com C++ - qualquer coisa pode ser reduzida a qualquer coisa lá.


Já percebi, obrigado pelo esclarecimento ))
 
Konstantin:

Não sei o que quer dizer com isso, mas este código:

Bem, tente compreendê-la. Comece por fazer com que o dynamic_cast funcione nos prós e contras. Se o descobrir por si próprio, estará muito melhor.
 
Renat Fatkhullin:

É verdade, não se pode conduzir de baixo para cima, apenas de cima para baixo.

Como assim, não se pode passar de uma classe base para um descendente?
 
Комбинатор:
Quer dizer que não se pode passar de uma classe base para um descendente?

Sim, no caso de a classe base não ter um descendente realmente construído.

 
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.

Se levarmos o ponteiro de cima para baixo, ou seja, para o pai, e depois passarmos o ponteiro para outro lugar no âmbito, será que os campos do descendente estão aí disponíveis?
 
Renat Fatkhullin:

Sim.

Renate, sabe o que é o dynamic_cast?
 
Комбинатор:
Renat, sabe o que é o dynamic_cast?

Claro que sim.

Veja-se a peça discutida do código MQL5. Cria-se uma instância de base e depois tenta-se heroicamente converter via dynamiccast a descendente, em violação da segurança. Bem, é uma chatice, claro.

 

O mesmo exemplo é directamente discutido e explicado na documentação. O elenco dinâmico em tempo de execução só é accionado depois de o sistema de segurança e a permissibilidade das conversões terem sido verificados. Cada objecto MQL5 tem todas as meta-informações para verificação dos direitos de execução. Isto não é C++ vazio.


Conversão do tipo dinâmico utilizando o operador dynamic_cast

É possível fundir dinamicamente tipos usando o operador dynamic_cast, que só pode ser aplicado a apontadores de classe. Neste caso, a verificação da correcção dos tipos é efectuada no momento da execução do programa. Isto significa que quando se utiliza o operador dynamic_cast, o compilador não verifica o tipo de dados utilizados para a conversão. Se a conversão de um ponteiro num tipo de dados, que não é o tipo de objecto real, for realizada, o resultado será NULL.

dynamic_cast<type-id> ( expressão )

O parâmetro do tipoid entre parênteses angulares deve ser um ponteiro para um tipo de classe previamente definido . Aexpressãotipo operando (em oposição a C++) pode ser qualquer coisa excepto nula.

Exemplo:

classe CBar { };
classe CFoo : CBarpúblico{ };

nuloOnStart( )
{
Barra CBar;
//---- o elenco dinâmico de tipo ponteiro *bar a ponteiro *pés é permitido
CFoo *foo =dynamic_cast<CFoo*>(&bar);//--- nenhum erro crítico de execução
Imprimir(foo);// foo=NULL
//--- é explicitamente proibido tentar lançar uma referência do objecto Bar a um objecto Foo
foo=(CFoo *)&bar;// ocorrerá um erro crítico de execução
Imprimir(foo);// esta linha não será executada
}

Razão: