Discussão do artigo "Usando os Ponteiros de Objeto no MQL5" - página 4

 
tol64:
Você encontrou uma falha de segurança? )
Sim, é ímpio fazer o cast diretamente dessa forma. Em vantagens, existe o dynamic_cast especificamente para essa finalidade; aqui você não pode converter de forma totalmente correta e é uma fonte potencial de erros implícitos e graves. E, em termos de seriedade, não é muito melhor do que ponteiros e referências inseguros.
 
denkir:

Não seria melhor usar o polimorfismo?

Aproximadamente:

O problema é que as classes herdeiras CChartObjectRectLabel, CChartObjectButton e CChartObjectEdit têm seus próprios métodos exclusivos que precisam ser acessados. E a classe base CChartObject da biblioteca padrão não tem os mesmos métodos virtuais.

 

No meu exemplo acima...

acesso a métodos de classes herdeiras?


... O resultado é o seguinte:

//--- objects[0]. // Como obter acesso aos métodos da classe CChartObjectEdit?
// 1.
   Print("((CChartObjectEdit *)objects[0]).BackColor(): ",((CChartObjectEdit *)objects[0]).BackColor());
//--- 2.
   CChartObjectEdit *e=(CChartObjectEdit *)objects[0];
   Print("e.BackColor(): ",e.BackColor());
   
//--- objects[1]. // Como acessar os métodos da classe CChartObjectButton?
// 1.
   Print("((CChartObjectButton *)objects[1]).State(): ",((CChartObjectButton *)objects[1]).State());
//--- 2.
   CChartObjectButton *b=(CChartObjectButton *)objects[1];
   Print("b.State(): ",b.State());
   
//--- objects[2]. // Como obter acesso aos métodos da classe CChartObjectRectLabel?
// 1.
   Print("((CChartObjectRectLabel *)objects[2]).BackColor(): ",((CChartObjectRectLabel *)objects[2]).BackColor());
//--- 2.
   CChartObjectRectLabel *r=(CChartObjectRectLabel *)objects[2];
   Print("r.BackColor(): ",r.BackColor());
 
TheXpert:
Sim. Não é ortodoxo fazer o cast diretamente dessa forma. Nos pontos positivos, existe o dynamic_cast especificamente para essa finalidade; aqui, você não pode fazer a conversão de forma totalmente correta e essa é uma fonte potencial de erros implícitos e graves. E, falando sério, não é muito melhor do que ponteiros e referências inseguros.

Sim, antes de fazer uma pergunta aqui no fórum, descobri na Internet que o C++ tem o operador dynamic_cast (um mecanismo de identificação dinâmica de dados).

Agora estou dando uma olhada no link acima:

// O mecanismo de identificação dinâmica do tipo de dados está disponível somente para os polimórficos 
// classes (ou seja, classes que contêm pelo menos uma função de membro virtual)

Então, essa é uma condição obrigatória? E se não houver métodos virtuais na classe base, então o dynamic_cast não funcionará?

P.S. >>> Aqui estou lendo mais sobre dynamic_cast (MSDN).

 
TheXpert:
Droga, e você fala sobre segurança de linguagem depois disso?

Você provavelmente acha que pode converter livremente para qualquer coisa, como em C/C++.

Não é assim e não há nada de errado com a segurança.

 
Renat:

Você provavelmente acha que pode converter livremente para qualquer coisa, como em C/C++.

Não é assim e não há nada de errado com a segurança.

Recebi esse erro por acidente, o que parece confirmar suas palavras. )

2014.11.06 14:33:36.588 OOP_Test (EURCHF,M5)   incorrect casting of pointers in 'Test1.mqh' (931,13)
 
Renat:

Não é e não há nada de errado com a segurança.

Não, normalmente não é possível fazer uma verificação dynamic_cast em tempo de compilação.
 
TheXpert:
Não, é impossível verificar dynamic_cast em tempo de compilação.

O comentário acima mostra o resultado da verificação de casting no rantime.

Ela é muito rígida e funciona no mecanismo RTTI, pois sabemos exatamente quem é quem no caso de fantasmas.

 
Renat:

O comentário acima mostra o resultado da verificação de transmissão no rantime.

Oops.... confuso. Pensei que fosse um compilador. Então, retiro o que disse.
 
O tutorial deixou claro para mim o entendimento do polimorfismo. Obrigado pela atenção