Errori, bug, domande - pagina 2363

 
Igor Makanu:

typedef è un argomento, ho provato, ma non è andata bene, devo ancora capire dove ho sbagliato, il mio esempio dovrebbe funzionare anche con typedef!

Il codice che ho scritto sopra dovrebbe funzionare. Volevo controllare io stesso, ma senza fortuna: =)))))))))))


(costruire 1961)

 
Igor Makanu:

typedef è un argomento, ho provato, ma non è andata bene, devo ancora capire dove ho sbagliato, il mio esempio dovrebbe funzionare anche con typedef!

Ma è possibile renderlo più semplice ed elegante - senza parentesi e puntatori inutili - (e si compila senza strani errori))))

#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:

Puoi renderlo più semplice ed elegante - senza parentesi e puntatori inutili - (e si compila senza strani errori))))

il tuo esempio non funziona nel mio caso, i miei oggetti sono creati dinamicamente, non gli assegno nemmeno un nome, mentre il tuo esempio usa un nome puntatore, ho provato in questo modo, il compilatore non lascia passare: '[' - name expected 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: ho iniziato a capire un po 'quello che suggerisci, ma ancora nessun risultato, posso fare a meno di dynamic_cast <>, aggiungere * campoCObject, in teoria dovrebbe essere così:

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

Penso che funzionerà un po' più velocemente del tuo esempio con dynamic_cast <> - il significato è lo stesso

 
Igor Makanu:

se è possibile dereferenziare un puntatore *CObject in MQL?

Ho provato diverse varianti, ecco uno script di prova, aggiungo 3 elementi Myclass alla lista collegata e poi cambio i valori dei campi CMyclass, funziona:

Posso modificare i campi degli elementi CMyclass creati dinamicamente, senza puntatore intermedioCMyclass *result?

Inquesto modo:(CMyclass *)(base.GetCurrentNode()).x = 99;

PS: sospetto che tu abbia bisogno di usare typedef, ma finora senza successo

Quello che hai scritto è solo un uso implicito dello stesso:

result=base.GetCurrentNode();

Cioè un tale puntatore anonimo, ma fondamentalmente solo zucchero sintattico. Non c'è quasi zucchero in MQL, quindi non può essere fatto in questo modo. Ma dovrei notare che il casting al discendente è fatto senza controlli e conversioni, quindi non è chiaro perché non ti piace il lavoro esplicito con un puntatore.

 
Igor Makanu:

ZS: un po 'iniziato a capire ciò che suggerisci, ma ancora nessun risultato, si può fare senza dynamic_cast <>, aggiungere un campo * CObject , in teoria, dovrebbe essere così:

Penso che funzionerà un po' più velocemente del tuo esempio con dynamic_cast <> - il significato è lo stesso

Si può fare senza un campo separato, come suggerito sopra, ma solo attraverso il wrapping nell'operatore.

C'è una piccola differenza. Se improvvisamente appare un oggetto non convertito in myclass, allora senza dynamic_cast ci sarà un errore di esecuzione, e con esso, si otterrà NULL in cambio. Se lo indirizzate con .x immediatamente, causerà comunque un errore di esecuzione, quindi non dovete preoccuparvi =)))

Se facciamo quello che ci ha ordinato il dottore dovremmo restituire qualcosa come un'istanza di classe speciale creata per la gestione degli errori ))))

P.S. Ho controllato la velocità di dynamic_casta recentemente, rispetto al solito casting - era quasi la stessa in caso di uguaglianza della classe con quella prevista.

P.S.S. In ogni caso, i for sembrano piuttosto tristi - quando si lavora con le liste si dovrebbero usare cicli come for each (come il mio ciclo)
 
Igor Makanu:

non passa il compilatore: '[' - nome atteso 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;
  }
//+------------------------------------------------------------------+

...

Cosa abbiamo effettivamente ottenuto con questo involucro? Un dynamic_cast inutile quando non è assolutamente necessario? Il wrapper stesso ha una conversione esplicita in CMyClass. Cioè ha 0% di carico di lavoro mentre il codice è più complicato (l'operatore di riferimento all'indice è usato come un operatore cast esplicito per la classe che viene passata - beh, non è affatto ovvio).

 
Ilya Malev:
P.S.S. In ogni caso, i for sembrano piuttosto tristi - quando si lavora con le liste, si dovrebbero usare cicli come for each (come il mio ciclo)

Scusa, ma è una cosa stupida.

 
Vasiliy Sokolov:

Quello che hai scritto è solo un uso implicito dello stesso:

Cioè un tale puntatore anonimo, ma fondamentalmente solo zucchero sintattico. Non c'è quasi zucchero in MQL, quindi non si può fare così. Ma dovrei sottolineare che il casting al discendente va avanti senza controlli e conversioni, quindi non è chiaro perché il lavoro esplicito con il puntatore sia così fastidioso.

Sì, lo capisco, sono ancora confuso con la sintassi in MQL quando si lavora con i puntatori, sembra la stessa del C++ standard, ma sono costantemente confuso e non posso né scrivere qualcosa subito, né leggere correttamente il codice della libreria dal pacchetto standard MT.... Mi sono strappato tutti i capelli! ... ma ancora sul .opera! )))) - Lo scoprirò comunque ;)


Ilya Malev:

C'è una differenza, una piccola differenza. Se capita che ci sia un oggetto non convertito in myclass, senza dynamic_cast ci sarà un errore di esecuzione, e con esso si otterrà solo NULL in cambio. Che comunque causerà un errore se lo indirizzate con .x immediatamente

Capisco tutto questo, e non è una differenza da poco, dirò sinceramente che il codice di un programmatore professionista differisce da uno dilettante proprio in questa differenza - nel controllare gli errori critici ..... anche se con le tendenze moderne nei linguaggi di programmazione è stato semplificato per i programmatori più pigri usando try eccetto finally etc. ;)

 
Vasiliy Sokolov:

Mi dispiace, ma questo è sciocco.

Oh, per favore.

 
Igor Makanu:

Sì, ho capito tutto, non riesco a capire la sintassi in MQL quando si lavora con i puntatori, sembra essere la stessa del C++ standard, ma sono costantemente confuso e non posso né scrivere qualcosa subito, né leggere correttamente il codice della stessa libreria dalla consegna standard MT.... Mi sono strappato tutti i capelli! ... ma ancora sul .opera! )))) - capirlo ;)

Prendere C++ come punto di riferimento in caso di MQL non funzionerà :) Il volume di ciò che è impossibile in MQL è molto più grande del volume dei costrutti "compatibili". Imho, MQL è più simile a un C# molto troncato con una completa mancanza di zucchero sintattico.