Aiuto con OOP - pagina 3

 
Vasiliy Sokolov #:

OK. Non capisco. Hai capito? Sei sicuro di aver capito? Esattamente?

L'argomento si riduce alla seguente affermazione:

...

Non si trattava di un argomento generale, ma di una situazione riguardante un singolo post, e ho spiegato qual era il problema. Ok, non c'è stata nessuna catastrofe.

 

Array dichiarato doppio x[268435448];

Lo stesso array nella funzione OnStart().

Ha anche fatto una chiamata ricorsiva con profondità LONG_MAX.

Nessun problema.

 
fxsaber #:

Non usate gli array statici?

Se la dimensione dell'array è piccola, costante e nota in anticipo, la statica è migliore e probabilmente più veloce.

 
Andrei Trukhanovich #:

Se la dimensione dell'array è piccola, costante e nota in anticipo, la statica è migliore e probabilmente più veloce.

Mi piacerebbe avere un modo per ottenere una lista di variabili/array statici e le loro dimensioni. Probabilmente c'è bisogno di un parser di codice come fatto qui.

Immagino che l'array statico di stringhe e l'array doppio siano cose molto diverse.

MQL5 Program Packer
MQL5 Program Packer
  • www.mql5.com
This is MQL5 project packer: assemble all source and resource files from dependencies into a single ZIP.
 
fxsaber #:

Immagino che la stringa statica e la doppia stringa siano cose molto diverse.

la stringa è essenzialmente una classe interna composta da un puntatore e una dimensione int, cioè per l'array doppio occuperà condizionatamente 1,5 volte meno spazio

Non credo che abbia molto senso preoccuparsene, a meno che non si abbiano array statici con milioni di elementi.

 
fxsaber #:

Non usare gli array statici?

Quindi ci sono essenzialmente quattro tipi di dati in MQL:

  • Dati statici e predefiniti. Si inserisce nel programma al momento della compilazione e non viene più modificato. Si trovano in uno spazio di memoria privata. Per esempio, questi sono array statici di tipo char[1024].
  • Dati gestiti manualmente attraverso i puntatori. Queste sono istanze di classi ma definite da un puntatore, per esempio CFoo* bar dove bar è un'istanza di CFoo. Queste istanze sono di tipo POINTER_DYNAMIC. Questo tipo di archiviazione è il più problematico, anche se non è richiesto nella maggior parte dei casi.
  • Dati gestiti dal raccoglitore di rifiuti della macchina virtuale mql in cui il programma è in esecuzione. Questo include le istanze delle classi. Il puntatore a un oggetto di questo tipo sarà POINTER_AUTOMATIC. Tali oggetti si trovano o nell'heap di questa macchina virtuale o nella sezione privata. Esattamente come dipende dai dati e dalla loro dimensione, apparentemente, e da quello che hanno gli sviluppatori. Questa informazione non è disponibile. Tali dati includono le classi di utenti, per esempio. Qualsiasi definizione di un'istanza di classe senza puntatore definisce questo tipo di memorizzazione. Per esempio CFoo bar definisce un'istanza di bar della classe CFoo, il cui puntatore non ha bisogno di essere liberato. La macchina virtuale esegue tutte le operazioni di rilascio. Non avete bisogno di usare l'operatore di cancellazione e quindi affrontate il problema della perdita di oggetti.
  • Dati che si trovano sullo stack. Queste sono, prima di tutto, variabili locali di funzioni. Cioè, quando scriviamo int a = 5 all'interno di qualsiasi funzione, la cima dello stack viene spostata di 4 byte verso l'alto, allocando così la dimensione di memoria necessaria. Forse, in MQL, i tipi memorizzati sullo stack includono anche le strutture (non ho mai controllato, per essere onesti). Tali dati non occupano molto posto, e anche tenendo conto di una catena di chiamate di funzioni annidate, lo stack nel suo insieme richiede molta meno memoria di un heap. Questo tipo di memorizzazione viene utilizzato automaticamente, non dovete pensarci.

Se lasciamo lo stack alle funzioni e alle loro variabili locali, ci rimangono tre tipi con cui lavorare. Personalmente credo (e questa è solo la mia opinione) che i dati definiti con durata automatica combinino bene i vantaggi dei due tipi precedenti, senza i loro svantaggi. I dati definiti con il puntatore automatico sono prevedibili e sicuri come quelli statici, ma altrettanto flessibili come quelli dinamici, controllati manualmente. Per prevedibilità intendo in scenari in cui non c'è bisogno di fare ulteriori controlli dei bit del puntatore e chiedersi se qualcun altro ha già cancellato i dati prima. Per flessibilità intendo scenari in cui si può lavorare con i dati referenziati da un puntatore automatico come con un puntatore regolare, passando il puntatore a una funzione o, per gli array, riciclandolo.

Per illustrare ciò che ho appena detto, potete confrontare il codice iniziale fornito da Ihor Herasko e lo stesso codice che ho scritto per POINTER_AUTOMATIC. Non ci sono controlli e inizializzazioni extra, nessun operatore cancella 60 000 000 di volte. Tutto questo vi fa risparmiare tempo, fatica e, cosa altrettanto importante, risorse. Se lo capite, non avete quasi mai bisogno di lavorare con i puntatori. Si può sempre scrivere un algoritmo del genere che minimizzi questo lavoro o che rimanga del tutto. Per esempio, non gestisco mai gli oggetti manualmente nel mio codice - non ce n'è proprio bisogno in qualche modo. Per quanto riguarda gli array statici, allora a volte devo usare, per esempio, per cucire nel programma i dati di cui ha bisogno, ma sono cose così speciali, che gli utenti comuni, presumo, non ne hanno bisogno. È meglio usare collezioni già pronte come CArrayObj, o le proprie. Ora i modelli e le capacità MQL permettono di creare cose abbastanza flessibili che sono molto meglio degli array statici.

 
Non c'è un raccoglitore di rifiuti nell'emcool.
 

Vasiliy Sokolov #:

Dati statici e predefiniti. Cucito nel programma al momento della compilazione e non più modificato. Sono memorizzati in un'area di memoria privata. Per esempio, questi sono array statici del tipo char[1024].

Se l'array non è inizializzato,

int A[] = {1, 2}; // Инициализация
int B[2];         // Без инициализации

perché dovrebbe essere scritto in EX5?

 
fxsaber #:

Se l'array non è inizializzato,

perché dovrebbe essere cucito in EX5?

Sì, è vero, quelli non inizializzati non sono cuciti, ovviamente. Quelli inizializzati saranno cuciti. Ma le dimensioni di entrambi i tipi sono definite al momento della compilazione e non cambiano più. Cioè, gli array statici possono essere condizionatamente divisi in due gruppi.

 
Dmitry Fedoseev #:
Non c'è un raccoglitore di rifiuti in emcool.

Ufficialmente, sì. Non ufficialmente, molte cose indicano che esiste:

  • Non ci sono puntatori in MQL. Invece, sono sostituiti da qualcosa che gli assomiglia molto.
  • Non c'è allocazione diretta della memoria in MQL, come in C per esempio;
  • I programmi in MQL sono eseguiti da una certa macchina virtuale. Renat ne ha scritto brevemente e non una volta;
  • L'istanza della classe può essere definita e poi sarà liberata automaticamente. Quindi, c'è qualche meccanismo che controlla queste istanze e le rilascia quando necessario. Che cos'è se non un raccoglitore di rifiuti?
  • Qualsiasi istanza inizializzata attraverso un puntatore e non adeguatamente liberata sarà marcata come oggetto leaked all'uscita. Il loro numero e la dimensione totale della memoria persa saranno stampati. Un programma con la memoria persa non sarà nemmeno convalidato nel Market. Quindi tutti gli oggetti, anche quelli assegnati manualmente, sono contabilizzati, conosciuti e noti al sistema. Questo è uno dei classici compiti che lo spazzino risolve.
Motivazione: