Domande dai principianti MQL5 MT5 MetaTrader 5 - pagina 192

 

Ho iniziato a imparare l'OOP e non riesco a superare il seguente ostacolo. Il seguente script è un esempio:

CSum result;
void OnStart()
  {
//---
  }
//+----------------------------------------+
class CSum
  {
public:
   int               Calculate(int A,int B);
  };
//---
int CSum::Calculate(int A,int B)
  {
   return(A+B);
  }

Senza la linea "CSum result;", il compilatore non genererà un errore. Ma causa un errore:

Dimmi cosa c'è che non va. Mi sembra di aver dichiarato correttamente l'oggetto della classe.

 
paladin800:

Ho iniziato a imparare l'OOP e non riesco a superare il seguente ostacolo. Il seguente script è un esempio:

Senza la linea "CSum result;", il compilatore non genererà un errore. Ma causa un errore:

Dimmi cosa c'è che non va. Mi sembra di aver dichiarato correttamente l'oggetto della classe.

Una variabile di tipo CSum (risultato) è dichiarata prima che la descrizione CSum sia fatta, il che significa che il compilatore non conosce ancora questo tipo. Inserire CSum all'inizio del file.
 
Lone_Irbis:
Inoltre, quanto può/deve essere sfruttato il sistema delle variabili globali? È possibile sovraccaricare qualcosa in questo modo o c'è un limite? Per esempio, diciamo due o più centinaia di variabili (di cui circa la metà si trasforma in input e back, a seconda di quale pezzo di codice richiede il test) e circa una dozzina e mezzo di piccoli array a livello globale - è molto o poco? ^^' E se ce ne sono due o tre volte di più man mano che si mette a punto il sistema? E se non dobbiamo farci prendere la mano, c'è un modo più semplice per gestire lo scambio di dati tra una dozzina di sottosistemi diversi, molti dei quali richiedono i risultati degli altri?
No, non c'è. Le variabili globali sono usate per altri scopi. Usare le classi per descrivere i sottosistemi. Ed è meglio evitare del tutto l'uso di array e variabili globali.
 
C-4:
Una variabile di tipo CSum (risultato) - è dichiarata prima che la descrizione CSum sia fatta, il che significa che il compilatore non conosce ancora questo tipo. Inserire CSum all'inizio del file.
Ops, ha funzionato. Ho messo la classe alla fine del codice per analogia con il posizionamento delle funzioni. Non mi aspettavo che per una classe un tale ordine potesse fare la differenza.
 
paladin800:
Ops, ha funzionato. Ho messo la classe alla fine del codice, simile al posizionamento delle funzioni. Non mi aspettavo che un tale ordine avrebbe fatto la differenza per la classe.
Sì, purtroppo l'ordine di precedenza è importante. Il caso più difficile è quando due classi si usano contemporaneamente. Qualsiasi classe introduciamo per prima, la seconda classe sarà sconosciuta al compilatore e genererà un errore. In questo caso non si può fare a meno della dichiarazione di classe. Nel tuo caso, è meglio separare CSum in un file separato, per esempio Sum.mqh e includerlo usando il dettato #include "Sum.mqh".
 
C-4:
No, non dovresti. Le variabili globali sono usate per altri scopi. Usare le classi per descrivere i sottosistemi. Ed è meglio non usare affatto gli array e le variabili globali.
Certo, capisco che è una buona idea usare le classi, ma sono ancora un po' pigro, considerando che è più familiare senza di esse, e sembrano funzionare in ogni caso. Ma sono solo curioso, qual è il loro vantaggio? Purché si sappia con certezza che il codice è scritto da un autore esclusivamente per se stesso e non sarà mai utile al di fuori di un particolare programma? Mi è sempre sembrato che le classi abbiano senso solo se stai scrivendo per qualcuno/qualcosa/vendere, mentre per te stesso come hobby non farà molta differenza. A parte l'estetica e il "così così" generale, c'è un senso pratico nel farsi coinvolgere in tutte queste classi-strutture? Velocità? C'è altro?
 
Lone_Irbis:
Naturalmente capisco che sarebbe bello avere a che fare con le classi, ma ancora sono troppo pigro, considerando che è più familiare senza di loro, e sembrano funzionare comunque. Ma sono solo curioso, qual è il loro vantaggio? Purché si sappia con certezza che il codice è scritto da un autore esclusivamente per se stesso e non sarà mai utile al di fuori di un particolare programma? Mi è sempre sembrato che le classi abbiano senso solo se stai scrivendo per qualcuno/qualcuno/vende, mentre per te stesso come hobby non farà molta differenza. A parte l'estetica e il "così così" generale, c'è un senso pratico nel farsi coinvolgere in tutte queste classi-strutture? La velocità? Qualcos'altro?

Al contrario. Quando si scrive un progetto personalizzato, il cliente spesso richiede il codice sorgente. E poi devi estrarre le funzioni dalle classi e inserirle nel codice sorgente. È meglio dare al cliente un solo file invece di trascinare una montagna delle vostre librerie, che contengono un numero enorme di funzioni, che non sono utilizzate nel lavoro passato al cliente. Cioè, è meglio usare la programmazione strutturata su richiesta.

Per le vostre esigenze, è meglio usare OOP - lì tutto è autosufficiente e non dovete preoccuparvi di passare il codice sorgente.

 
artmedia70:

Al contrario. Quando si scrive un progetto personalizzato, il cliente spesso richiede il codice sorgente. E poi devi estrarre le funzioni dalle classi e inserirle nel codice sorgente. È meglio dare al cliente un solo file invece di trascinare una montagna delle vostre librerie, che contengono un numero enorme di funzioni, che non sono utilizzate nel lavoro passato al cliente. Cioè, è meglio usare la programmazione strutturata per un cliente.

È meglio usare OOP per le proprie esigenze - tutta la tua roba è lì, e non devi preoccuparti di trasferire il codice sorgente.

Hmmm... Beh, forse è così :) Questo è, naturalmente, il principio sembra allettante... in teoria. Soprattutto tenendo conto che non posso fare un solo file senza strutture o classi. Il fatto è che scrivo soprattutto per interesse, testando le mie teorie casuali e inventando biciclette infinite. In parallelo, studio solo ciò che comincia ad essere necessario per implementare l'idea. Tutto questo avviene nell'ambito di un unico Expert Advisor in fase di apprendimento e sperimentazione - inizialmente un semplice martin, ma ora è più uno scalper multifunzionale in erba (e già teoricamente redditizio). Quindi, ad un certo punto il robot è diventato banalmente troppo grande. >.> Quando la maggior parte del tempo è stato speso solo a scorrere la rotella del mouse alla ricerca del pezzo di codice giusto, ho avuto l'idea "geniale" di farne dei file separati (13 parti collegabili al momento), raggruppando solo le funzioni per il loro concetto generale. Come il parser delle notizie qui, l'elaborazione dei livelli lì, un altro con i controller dell'alce, le statistiche separatamente, ecc. Ma a quel tempo il mio entusiasmo per affrontare l'OOP non era sufficiente...

Quindi il mio problema sembra essere che sto prendendo ogni idea che mi viene in mente e la sto completando sopra un robot esistente in un modo piuttosto... sequenza caotica. Il risultato è piuttosto bizzarro, con tutti i tipi di interruttori e combinazioni di modalità, molte delle quali sono lasciate in sospeso. Il tutto è completato da centocinquanta variabili globali, che devono essere rimosse dagli input, solo per non prendere tanto tempo, essendo impresse nel visualizzatore del tester all'inizio. Più, naturalmente, montagne di spazzatura e rudimenti di idee abbandonate o riprogettate.

E sembra essere un buon momento per ordinare tutto questo mucchio di spazzatura e mettere tutto in classi (e prima di tutto leggere almeno un articolo su OOP senza addormentarsi nel processo)... Ma sono confuso dalla quantità di lavoro da fare e, ahem, dalla sua relazione con il senso potenziale dell'intera faccenda. Questo è per concludere tutto in classi - non sembra un compito così volumetrico... Ma avrebbe senso, se, per esempio, scaricare tutto in una fila in pubblico, ignorando tutti questi privati/protetti? Come può essere meglio che avere una cartella con un mucchio di .mph e una dozzina di funzioni comuni ciascuno, se poi finiscono tutti in un robot?

 
Lone_Irbis:

Ti consiglierei di fare un unico modello, che ha già tutti i passi necessari per l'inizializzazione, la connessione, la raccolta dei dati sempre necessari, ecc...

Mi è venuta in mente un'idea inaspettata: caricare un modello, rinominarlo e scriverci solo ciò che è rilevante per quella particolare idea. E quelle funzioni che usate sempre, in qualsiasi codice, restituendo gli stessi dati in qualsiasi situazione - mettetele nelle classi. E tutto andrà subito al suo posto. Si possono anche strutturare le directory. In \experts\creo (l'ho fatto così) una cartella chiamata Ordini, dove metto anche tutti i file appartenenti a diversi clienti in cartelle separate, ho una cartella chiamata Idee, Test, ecc.

In questo modo, si può mantenere l'ordine.

 
Purtroppo, anche imparando formalmente l'OOP, non sarete in grado di costruire un programma OOP. Piuttosto, è necessario entrare nella filosofia di questo approccio, e questo è il livello successivo alla conoscenza formale. Così si scopre che ne hai davvero bisogno? Ma se fai domande su come farlo meglio, significa che senti che il modo che hai scelto non è ottimale. In ogni caso, la scelta è vostra.
Motivazione: