Domande su OOP in MQL5 - pagina 82

 
Igor Makanu:

non importa cosa inizializzare, anche int - qualsiasi numero per chiamare questo costruttore

e ho scelto 0.0 per evitare errori di stampa - qualsiasi cifra, cioè 0.0. È più difficile da scrivere e sbagliare rispetto a 123

(doppio)0

ma neanche così)))) appena adesso ha guardato il codice normalmente, c'è ancora un modo per guardarlo in modo anomalo))
 
Alexandr Andreev:

(doppio)0

no

Scrivo solo 0,0 - non sono previsti altri numeri - non c'è nemmeno una variabile nel costruttore

in generale, come stile di un autore alla moda, probabilmente non il migliore

 
Alexandr Andreev:

il punto non è la x) ma che ci può essere un float sul ricevitore, e non è affidabile nemmeno specificare 0,0

0.0 è un doppio non ambiguo per il compilatore, float sarà 0.f
 
Vladimir Simakov:
0.0 è un doppio inequivocabile per il compilatore, float sarà 0.f

credito)

 

Mentre la sezione "domande over 50" è aperta, permettetemi di interporre la mia sull'argomento dei calchi.

- Quali sono alcuni modi per migliorare il codice in termini di tolleranza agli errori o non ridondanza?

- È necessario il controlloCheckPointer()!=POINTER_INVALID? O decisamente non necessario? Spiega perché.

- portando a non-const, in modo che sia possibile chiamare metodi non-const. I metodi non-const possono essere chiamati direttamente nel metodo Compare ? Cioè sbarazzarsi del giallo evidenziato const ?

#include <ChartObjects\ChartObjectsShapes.mqh>

class CChartObjectRectangleX : public CChartObjectRectangle
  {
public:

   void CChartObjectRectangleX(){};      
   virtual int       Compare(const CObject *node,const int mode=0) const 
   {
   CChartObjectRectangleX *n=NULL;
   const CChartObjectRectangleX*nc=dynamic_cast<const CChartObjectRectangleX*>(node);
   if(nc!=NULL)
   n=(CChartObjectRectangleX *) nc;
   if(n!=NULL) {
     if(mode==0) return CompareDate(n); 
     if(mode==1) return CompareValue(n); }return 0;    }
 
   virtual int       CompareDate( CChartObjectRectangleX *node) const { 
   //if(node!=NULL) 
      return (this.Time(1)-node.Time(1)); return 0;    }
    virtual int       CompareValue( CChartObjectRectangleX *node) const { 
   //if(node!=NULL) 
      return ((this.Price(1)-node.Price(1))*10/Point()); return 0;    }
};
 
Aleksey Mavrin:

Mentre la sezione "domande over 50" è aperta, permettetemi di interporre la mia sull'argomento dei calchi.

- Quali sono alcuni modi per migliorare il codice in termini di tolleranza agli errori o non ridondanza?

- È necessario il controllo CheckPointer()!=POINTER_INVALID? O decisamente non necessario? Spiega perché.

- portando a non-const, in modo che sia possibile chiamare metodi non-const. I metodi non-const possono essere chiamati direttamente nel metodo Compare ? Cioè sbarazzarsi del giallo evidenziato const ?

class CChartObjectRectangleX : public CChartObjectRectangle
  {
public:
   virtual int       Compare(const CObject *node,const int mode=0) const
   {
   const CChartObjectRectangleX *n=dynamic_cast<const CChartObjectRectangleX*>(node);
   return !n?0: mode==0?CompareDate(n):CompareValue(n);}
   
   virtual int CompareDate(const CChartObjectRectangleX *node) const {return !node?0:int(Time(1)-node.Time(1));}
   virtual int CompareValue(const CChartObjectRectangleX *node) const {return !node?0:(int)MathRound(((Price(1)-node.Price(1))*10/Point()));}
};

È un po' come il tuo, solo con meno lettere. È una questione di gusti, a chi piace di più, ma ho rimosso la variabile extra (il compilatore probabilmente la rimuoverebbe anche nel quadro dell'ottimizzazione).

Per quanto riguarda il mio controllo dei nodi. Deve essere sostituito con CheckPointer(node)==POINTER_INVALID, ma è un overhead - una chiamata di funzione. Anche se è inlined, è comunque almeno dereferenziato e controlla il flag di stato. Se solo library o concrete, avete scritto il programma userà i metodi Compare, meglio !node e sul codice per guardare se il puntatore non è valido. Se siete troppo pigri per fare attenzione ai puntatori o se è una libreria per sfigati, solo CheckPointer(node)==POINTER_INVALID.

Se rimuovete lo specificatore const che avete evidenziato, non potete chiamare questi metodi da un oggetto costante.

UPD: il controllo evidenziato può essere rimosso, perché è nei metodi chiamati.

 
Aleksey Mavrin:

Mentre la sezione "domande over 50" è aperta, permettetemi di interporre la mia sull'argomento dei calchi.

- Quali sono alcuni modi per migliorare il codice in termini di tolleranza agli errori o non ridondanza?

- È necessario il controllo CheckPointer()!=POINTER_INVALID? O decisamente non necessario? Spiega perché.

- portando a non-const, in modo che sia possibile chiamare metodi non-const. È possibile chiamare un metodo non-const direttamente nel metodo Compare ? Cioè sbarazzarsi del giallo evidenziato const ?

L'idea è di scrivere due metodi della stessa funzione con e senza il corpo const - a dir poco - non ne vale la pena))))

Ma la probabilità di incontrare due metodi è vicina allo zero.... Perché la possibilità di esistenza diCChartObjectRectangle::Price - senza const nel corpo - penso sia improbabile.

La chiamata di questa funzione dall'esterno non ha alcun effetto. Cioè la const funziona solo con le funzioni interne e si assicura che nulla sia stato scritto nella memoria dell'oggetto (non ha cambiato il valore della variabile). In altre parole, non potete chiamare Set(a) durante la cost... Spesso, in un po' di confusione, per assicurarsi che questa funzione non sovrascriva nulla, si possono sistemare rapidamente queste consts (anche se questa è probabilmente la mia cancellazione).

Considerate che le consts dovrebbero essere infilate proprio ovunque senza ottenere)))) per rendere più facile controllare qualcosa in seguito.


CheckPointer()!=POINTER_INVALID ha bisogno di un controllo?

E perché no.... farne uno bool Check(<template> &T) { retun CheckPointer(T)!=POINTER_INVALID } Il compilatore dovrebbe renderlo il più semplice possibile. E sarà ancora più bello.

È più veloce.

int a[1000];
for (int i=0; i<ArraySize(a); i++)....
или
for (int i=ArraySize(a); i>=0; i--)....
дак вот разницы не должно быть вообще


Beh, non ho cambiato molto.

template<typename T>
bool Check(T *a) {return CheckPointer(a)!=POINTER_INVALID;};

class CChartObjectRectangleX : public CChartObjectRectangle
  {
  #define  ME CChartObjectRectangleX
public:
   void ME(){};      
   virtual int       Compare(const CObject *node,const int mode=0) const 
   {
   const ME*nc=dynamic_cast<const ME*>(node);
   return Check(nc)?mode==0?CompareDate(nc):CompareValue(nc):0;
   } 
   virtual int       CompareDate(const ME *node) const            {return (this.Time(1)-node.Time(1));}
   virtual int       CompareValue(const ME *node) const           {return ((this.Price(1)-node.Price(1))*10/Point()); }
 #undef  ME
};

Questo è tutto il tuo codice.

 
Vladimir Simakov:

Sembra essere lo stesso del tuo, solo con meno lettere. Quindi, è una questione di gusti, ma ho rimosso la variabile extra (molto probabilmente, il compilatore l'avrebbe rimossa come parte dell'ottimizzazione).

Per quanto riguarda il mio controllo dei nodi. Deve essere sostituito con CheckPointer(node)==POINTER_INVALID, ma è un overhead - una chiamata di funzione. Anche se è inlined, è comunque almeno dereferenziato e controlla il flag di stato. Se solo library o concrete, avete scritto un programma che userà i metodi Compare, meglio !node e sul codice per guardare se il puntatore non è valido. Se siete troppo pigri per fare attenzione ai puntatori o se è una libreria per sfigati, solo CheckPointer(node)==POINTER_INVALID.

Se rimuovete lo specificatore const, non potete chiamare questi metodi da un oggetto costante.

mi ci è voluto molto tempo per aprire la scheda


Immagino che 4 anni di università non abbiano aggiunto molto alla mia conoscenza (la spiegazione è in ritardo nella spazzatura).

 

la variante senza la costituzione, poiché la classe base non ha alcun riferimento ai parametri di input, funzionerà anche correttamente, sebbene questo non sia uno stile molto intelligente

#include <ChartObjects\ChartObjectsShapes.mqh>

template<typename T>
bool Check(T *a) {return CheckPointer(a)!=POINTER_INVALID;};

class CChartObjectRectangleX : public CChartObjectRectangle
  { #define  ME CChartObjectRectangleX
public: 
   void ME(){};      
   virtual int       Compare(CObject *node,int mode=0) 
   {
   ME*nc=dynamic_cast<ME*>(node);
   return Check(nc)?mode==0?CompareDate(nc):CompareValue(nc):0;
   } 
   virtual int       CompareDate(ME *node)             {return (this.Time(1)-node.Time(1));}
   virtual int       CompareValue(ME *node)            {return ((this.Price(1)-node.Price(1))*10/Point()); }
 #undef  ME
};
 

Anche una variante dello stesso codice.

template<typename T>
bool Check(T *a) {return CheckPointer(a)!=POINTER_INVALID;};

class CChartObjectRectangleX : public CChartObjectRectangle
  { #define  ME CChartObjectRectangleX
public: 
   void ME(){};      
   virtual int       Compare(CObject *node,int mode=0)      {return Check(node)?mode==0?CompareDate(node):CompareValue(node):0;} 
   virtual int       CompareDate(CObject *node)             {return (  Time(1)-dynamic_cast<ME*>(node).Time(1));}
   virtual int       CompareValue(CObject *node)            {return ((Price(1)-dynamic_cast<ME*>(node).Price(1))*10/Point()); }
 #undef  ME
};


È lo stesso con le costanti.

template<typename T>
bool Check(T *a) {return CheckPointer(a)!=POINTER_INVALID;};

class CChartObjectRectangleX : public CChartObjectRectangle
  { #define  ME CChartObjectRectangleX
public: 
   void ME(){};      
   virtual int       Compare(CObject const *node,int const mode=0)   const{return Check(node)?mode==0?CompareDate(node):CompareValue(node):0;} 
   virtual int       CompareDate(CObject const *node)                const{return (  Time(1)-dynamic_cast<const ME*>(node).Time(1));}
   virtual int       CompareValue(CObject const *node)               const{return ((Price(1)-dynamic_cast<const ME*>(node).Price(1))*10/Point()); }
 #undef  ME
};
Motivazione: