Erros, bugs, perguntas - página 2363

 
Igor Makanu:

typedef é um tema, eu tentei, mas não correu bem, ainda tenho de descobrir onde fiz asneira, o meu exemplo também deve funcionar com typedef!

O código que escrevi acima deve funcionar. Eu próprio quis verificar, mas sem sorte: =)))))))))))


(construção 1961)

 
Igor Makanu:

typedef é um tópico, eu tentei, mas não correu bem, ainda tenho de descobrir onde fiz asneira, o meu exemplo também deve funcionar com typedef!

Mas pode torná-lo mais simples e elegante - sem parênteses e apontadores desnecessários - (e compila sem erros estranhos))))

#property strict

class CObject{ };
class CMyclass: public CObject {
  public: CMyclass *operator[] (CObject*p){ CMyclass*r = dynamic_cast<CMyclass*>(p); 
                                return CheckPointer(r)!=POINTER_INVALID?r:NULL; }
          int f(){ return 1; } 
} my ;

void OnStart()
{
  CObject*co=new CMyclass;
  
  my[co].f();
}
 
Ilya Malev:

Pode torná-lo mais simples e elegante - sem parênteses e apontadores desnecessários - (e compila sem erros estranhos))))

o vosso exemplo não funciona no meu caso, os meus objectos são criados dinamicamente, nem sequer lhes atribuo um nome, enquanto o vosso exemplo usa um nome ponteiro, tentei assim, o compilador não deixa passar: '[' - nome esperado tst_cast.mq4 32 15


#property strict
#include <Object.mqh>
#include <Arrays\List.mqh>
//+------------------------------------------------------------------+
class CMyclass:public CObject
  {
public:
   int               x;
   double            y;
   CObject           *obj;
   void              CMyclass(void):x(-1),y(-2.2)  {                       }
   public: CMyclass *operator[] (CObject*p){ CMyclass*r = dynamic_cast<CMyclass*>(p); 
                                             return CheckPointer(r)!=POINTER_INVALID?r:NULL; }         
  };
//+------------------------------------------------------------------+
void OnStart()
  {
   CList *base=new CList;
   for(int i=0;i<3;i++)
     {
      base.Add(new CMyclass);
      ((CMyclass*)base.GetCurrentNode()).x = 99;
      ((CMyclass*)base.GetCurrentNode()).y = 555;
      CMyclass[base.GetCurrentNode()].x = 111;
     }

   for(int i=0;i<3;i++)
     {
      Print(((CMyclass*)base.GetNodeAtIndex(i)).x," : ",((CMyclass*)base.GetNodeAtIndex(i)).y);
     }
   delete base;
  }
//+------------------------------------------------------------------+

SZZ: Comecei a compreender um pouco o que sugere, mas ainda sem resultado, posso fazer sem dynamic_cast <>, adicionar * campoCObject, em teoria deveria ser assim:

...
 CObject           *obj;
 CMyclass          *operator[](CObject*p)        { obj = p; return(obj); }          
  };

Penso que funcionará um pouco mais rápido que o vosso exemplo com dynamic_cast <> - o significado é o mesmo

 
Igor Makanu:

se for possível desreferenciar um *pontador abjecto em MQL ?

Experimentei diferentes variantes, aqui está um guião para teste, adiciono 3 elementos Myclass à lista ligada e depois mudo os valores dos campos CMyclass, funciona:

Posso modificar campos de elementos CMyclass criados dinamicamente, sem ponteiro intermédioCMyclass *resultado ?

Como isto:(CMyclass *)(base.GetCurrentNode()).x = 99;

PS: Suspeito que precise de usar typedef , mas até agora sem sucesso

O que escreveu é apenas uma utilização implícita do mesmo:

result=base.GetCurrentNode();

Isto é, um ponteiro tão anónimo, mas essencialmente apenas açúcar sintáctico. Quase não há açúcar no MQL, pelo que não pode ser feito dessa forma. Mas devo notar que o casting para descendente é feito sem quaisquer verificações e conversões, por isso não é claro porque não se gosta de trabalho explícito com um ponteiro.

 
Igor Makanu:

ZS: um pouco começou a compreender o que sugere, mas ainda sem resultado, pode fazer sem dynamic_cast <>, adicionar um campo * CObject , em teoria, deveria ser assim:

Penso que funcionará um pouco mais rápido que o seu exemplo com dynamic_cast <> - o significado é o mesmo

Pode fazê-lo sem um campo separado, como sugerido acima, mas apenas através de embrulho no operador.

Há uma pequena diferença. Se de repente aparecer um objecto não convertido para a minha classe, então sem o dynamic_cast haverá um erro de execução, e com ele, receberá NULL em troca. Se o endereçar com .x imediatamente, causará erro de execução de qualquer forma, pelo que não precisa de se preocupar com isso =))))

Se fizermos o que o médico ordenou, devemos devolver algo como uma instância de classe especial criada para o tratamento de erros ))))

P.S. Verifiquei recentemente a velocidade do dynamic_casta, em comparação com o casting habitual - era quase o mesmo em caso de igualdade de classe a esperar um.

P.S.S. Em todo o caso, para parecer um pouco triste - ao trabalhar com listas, deve usar loops como para cada um (como o meu loop)
 
Igor Makanu:

não passa compilador: '[' - nome esperado tst_cast.mq4 32 15

#property strict
#include <Object.mqh>
#include <Arrays\List.mqh>
//+------------------------------------------------------------------+
class CMyclass:public CObject
  {
public:
   int               x;
   double            y;
   CObject           *obj;
   void              CMyclass(void):x(-1),y(-2.2)  {                       }
   public: CMyclass *operator[] (CObject*p){ CMyclass*r = dynamic_cast<CMyclass*>(p); 
                                             return CheckPointer(r)!=POINTER_INVALID?r:NULL; }         
  };
//+------------------------------------------------------------------+
void OnStart()
  {
   CList *base=new CList;
   for(int i=0;i<3;i++)
     {
      base.Add(new CMyclass);
      ((CMyclass*)base.GetCurrentNode()).x = 99;
      ((CMyclass*)base.GetCurrentNode()).y = 555;
      CMyclass[base.GetCurrentNode()].x = 111;
     }

   for(int i=0;i<3;i++)
     {
      Print(((CMyclass*)base.GetNodeAtIndex(i)).x," : ",((CMyclass*)base.GetNodeAtIndex(i)).y);
     }
   delete base;
  }
//+------------------------------------------------------------------+

...

O que é que conseguimos de facto com este invólucro? Uma transmissão_dinâmica desnecessária quando é absolutamente desnecessária? O próprio invólucro tem uma conversão explícita para CMyClass. Ou seja, tem 0% de carga de trabalho enquanto o código é mais complicado (o operador de referência do índice é utilizado como um operador de conversão explícito para a classe a ser passada - bem, não é nada óbvio).

 
Ilya Malev:
P.S.S. Em todo o caso, o for's parece bastante triste lá - ao trabalhar com listas, deve usar loops como para cada um (como o meu loop)

Desculpe, mas isso é uma tolice.

 
Vasiliy Sokolov:

O que escreveu é apenas uma utilização implícita do mesmo:

Ou seja, um ponteiro tão anónimo, mas basicamente apenas açúcar sintáctico. Quase não há açúcar no MQL, por isso não se pode fazer isso dessa forma. Mas devo salientar que o casting para descendente continua sem quaisquer verificações e conversões, por isso não é claro porque é que o trabalho explícito com o ponteiro é tão irritante.

Sim, eu compreendo, ainda me confunde a sintaxe no MQL quando se trabalha com apontadores, parece o mesmo que no C++ padrão, mas estou constantemente confuso e não consigo escrever algo imediatamente, nem ler correctamente o código da biblioteca do pacote MT.... padrão Arranquei todo o meu cabelo para fora! ... mas ainda no .opera! )))) - Eu vou descobrir de qualquer maneira ;)


Ilya Malev:

Há uma diferença, uma pequena diferença. Se por acaso houver um objecto não convertido para a minha classe, sem dynamic_cast haverá um erro de execução, e com ele receberá apenas NULL em troca. O que, de qualquer forma, causará um erro se o tratar com .x imediatamente.

Compreendo tudo isto, e não é uma pequena diferença, direi sinceramente que o código de um programador profissional difere do código de um amador nesta mesma diferença - na verificação de erros críticos ..... embora com tendências modernas em linguagens de programação tenha sido simplificado para programadores de lamas que utilizam a tentativa excepto finalmente, etc. ;)

 
Vasiliy Sokolov:

Lamento, mas isto é uma parvoíce.

Por favor.

 
Igor Makanu:

Sim, compreendo tudo, não consigo perceber a sintaxe em MQL quando trabalho com apontadores, parece ser o mesmo que em C++ padrão, mas estou constantemente confuso e não consigo escrever algo de imediato, nem ler correctamente o código da mesma biblioteca a partir da entrega MT.... padrão Arranquei todo o meu cabelo para fora! ... mas ainda no .opera! )))) - descubra-o ;)

Tomar C++ como ponto de referência em caso de MQL não funcionará :) O volume do que é impossível no MQL é muito maior do que o volume das construções "compatíveis". Imho, MQL é mais como um C# muito truncado com uma completa falta de açúcar sintáctico.