Domande su OOP in MQL5 - pagina 43

 
Igor Makanu:

SZS: I tuoi post sono quasi sempre ragionevoli, ma la presentazione del materiale, beh, non esattamente con buone intenzioni, ovviamente i tuoi affari, ma imho, vuoi aiutare - aiutare, vuoi essere intelligente, beh, spesso risulta così

Il lancio ti fa pensare... hai scritto che hai cominciato a pensare al codice, e prima stavi codificando a comando...

 
A100:

Il lancio ti fa pensare... hai scritto che hai iniziato a pensare al codice, e che prima stavi codificando in fretta e furia.

hmm... Beh, non ho mai scritto un'inezia! - questo è un fatto!

SZZY: aggiorno il topic periodicamente, non per ignoranza o perché non riesco a trovare il materiale da solo, ma perché c'è un attivo, che mi interessa ;)

ZSYS: il risultato della comunicazione - piuttosto ripensato perché usare i modificatori, perché abbiamo bisogno di un get/set - si risparmia tempo sulla fase di sviluppo, con l'uso sapiente del compilatore, testando il codice scritto sarà immediatamente successo - qui davvero aperto gli occhi, che era una risorsa nel tema, ancora una volta, grazie!

 
Koldun Zloy:

Ecco un esempio:

Dal tuo codice, non è chiaro a cosa serva l'interfaccia, quindi l'ho buttata via.

Naturalmente non conosco completamente il vostro compito, ma c'è una probabilità del 99,99% che non sia necessario.

Malvagio...

 
Igor Makanu:

Ehm... Beh, non ho mai scritto in modo confuso! - questo è un fatto!

SZZY: aggiorno periodicamente questo topic non per ignoranza, o perché non riesco a trovare materiale per conto mio, ma perché c'è una risorsa, la cui opinione mi interessa ;)

SZZY: il risultato della comunicazione - piuttosto ripensato perché usare i modificatori, perché abbiamo bisogno di un get/set - si risparmia tempo in fase di sviluppo, con un uso sapiente del compilatore, testando il codice scritto sarà immediatamente successo - qui davvero aperto gli occhi, che era una risorsa nel tema, ancora una volta, grazie!

È molto bello che tu abbia imparato qualcosa. Ma potete fare molti più progressi se leggete il C++ di Stroustrup.

Ma è meglio non leggere articoli e video vari su Habra. Chiunque può scrivere lì. Vi confonderanno soltanto.

 

È sorta una domanda.


C'è un pannello con dei pulsanti, ogni pulsante eseguirà alcune funzioni. Le funzioni chiamate dalla pressione di uno dei pulsanti, chiamiamolo Exit1, dovrebbero essere collocate in una classe separata CExit1.

Ma queste funzioni usano alcune variabili globali e metodi di altri oggetti.

Non ho partecipato a grandi progetti. Vorrei conoscere il parere di un esperto, come farlo correttamente?

Spesso programmo in modo tale che se un file mq4 viene compilato, tutte le classi e gli include-files vengono caricati senza errori e l'EA funziona correttamente. Tuttavia, se compilo una classe separatamente, ottengo avvisi perché alcune variabili e funzioni esterne non sono visibili.

Ecco la mia domanda. Una classe deve compilare se stessa senza errori, voglio dire, deve contenere tutte le copie delle variabili globali di EA, i riferimenti agli oggetti, ecc. Se sì, quando sarebbe il momento migliore per farlo? Se ci sono molti oggetti che interagiscono, come organizzarli in modo che ci sia meno confusione? Crei diagrammi dei tuoi programmi se proliferano?

Condividi come scrivi e realizzi il lavoro con i tuoi oggetti.

 
Vasiliy Pushkaryov:

È sorta una domanda.


C'è un pannello con dei pulsanti, ogni pulsante eseguirà alcune funzioni. Le funzioni chiamate dalla pressione di uno dei pulsanti, chiamiamolo Exit1, dovrebbero essere collocate in una classe separata CExit1.

Ma queste funzioni usano alcune variabili globali e metodi di altri oggetti.

Non ho partecipato a grandi progetti. Vorrei conoscere il parere di un esperto, come farlo correttamente?

Spesso programmo in modo tale che se un file mq4 viene compilato, tutte le classi e gli include-files vengono caricati senza errori e l'EA funziona correttamente. Tuttavia, se una classe viene compilata separatamente, potrebbe avere degli avvertimenti perché alcune variabili e funzioni esterne non sono visibili.

La domanda è. È necessario che la classe stessa si compili senza errori, cioè che contenga già tutte le copie utilizzate delle variabili globali, i riferimenti agli oggetti, ecc. Se sì, quando sarebbe il momento migliore per farlo? Se ci sono molti oggetti che interagiscono, come organizzarli in modo che ci sia meno confusione? Crei schemi per i tuoi programmi se proliferano?

Condividi come scrivi e realizzi il lavoro con i tuoi oggetti.

Le variabili globali e le statistiche, tranne quelle inerenti alla piattaforma, sono una cosa malvagia. E tutte le entità (gruppi di classi) devono essere isolate e comunicare tra loro secondo un protocollo (quello dell'interfaccia) e nient'altro.

Questo è naturalmente l'ideale :-) Nella vita reale sei tu a prendere la decisione e a sostenere te stesso, perché nessun altro conosce il tuo progetto, la tua idea e il tuo stile.

 
struct A
{
   int x,y;
};

//+------------------------------------------------------------------+
void OnStart()
{
   A a,b,c;
   a.x = 1;
   a.y = 2;
   b = a;
   c = a;
   //b = c = a;  //'operator=' - parameter passed as reference, variable expected
}

1. perché non compila?

2. c'è un trucco per descrivere operator= , e usare l'operatore di copia nativo in esso? .... cioè un modo per chiamare::=

 
Igor Makanu:

1. perché non compila?
2. c'è un trucco per descrivere operator= , e usare l'operatore di copia nativo in esso? .... cioè un modo per chiamare ::=

1) l'operatore di assegnazione predefinito in MQL restituisce il tipo di dati void;
2) si può fare qualcosa del genere:

struct A{
   int x,y;
   
   A(){}
   A(const A &a){
      this.x = a.x;
      this.y = a.y;
   }
   A operator=(const A &a){
      this.x = a.x;
      this.y = a.y;
      return a;
   }
};

void OnStart(){
   A a,b,c;
   a.x = 1;
   a.y = 2;
   b = a;
   c = a;
   b = c = a;  
}
 
Sergey Dzyublik:

1) l'operatore di assegnazione predefinito in MQL restituisce dati di tipo void;

non sono d'accordo:

struct A
{
   int x[];
};
//+------------------------------------------------------------------+
A myfunc(const int size)
{
   A result;
   ArrayResize(result.x, size);
   for(int i = 0; i < size; i++) result.x[i] = i + 1;
   return(result);
}
//+------------------------------------------------------------------+
void OnStart()
{
   A a;
   a = myfunc(5);
   A b;
   b = a;            // скопировали
   b.x[0] = 99;      // изменили 1-й элемент, чтобы убедиться, что это копия а, а не ссылка как в C#
   ArrayPrint(a.x);
   ArrayPrint(b.x);
}
//+------------------------------------------------------------------+

2020.04.18 18:54:03.855 tst (EURUSD,H1) 1 2 3 4 5

2020.04.18 18:54:03.855 tst (EURUSD,H1) 99 2 3 4 5


Chiaramente l'operatore di assegnazione predefinito restituisce il tipo di dati completo e fa una copia, o di quale vuoto stiamo parlando?


2. l'esempio è buono, ma voglio preservare la possibilità di copiare in strutture di array con l'operatore di copia predefinito - l'ho controllato, in generale funziona abbastanza bene con gli array dinamici, ci sono un paio di sfumature, ma la questione è diversa per ora

 
Igor Makanu:

L'operatore di assegnazione predefinito restituisce chiaramente il tipo di dati completo e fa una copia, o di quale vuoto stiamo parlando?

Sbagliato.

Basta definire il vostro operator=, che restituisce questo, e vedrete la differenza.

Lo si può vedere quando il risultato dell'assegnazione viene assegnato di nuovo.

struct A
{
   int x;
   int y;
   
   A operator=( const A& a )
   {
      x = a.x;
      y = a.y;
      
      return this;
   }
};

void OnStart()
{
   A a,b,c;
   a.x = 1;
   a.y = 2;
   b = a;
   c = a;
   b = c = a;
}