Domande su OOP in MQL5 - pagina 11

 
Dmitry Fedoseev:

E a proposito di uccelli... i descrittori sono anche puntatori. E sapete, non cambia nulla dalla parola stessa, che sia un descrittore, un puntatore, un identificatore.

la realizzazione fisica di queste parole è stata a lungo nascosta agli utenti

imho è più o meno così

- descrittore - è legato al metodo che implementa questa funzionalità nel sistema

- un handle - è tutto uguale a un descrittore, ma il SO lo implementa

- un puntatore e un identificatore sono pensati per lavorare con la memoria fisica

 
Dmitry Fedoseev:

E se dovete passare un puntatore a una funzione per creare un oggetto nella funzione, è così che funziona:

class CObj{
   public:
   int f(){
      return(33);
   }
};

CObj * obj;

void OnStart(){
  z(obj);
  delete(obj);
}

void z(CObj & o){
   o = new CObj();
}
Questo è in realtà tutto quello che volevate sapere sull'OOP, ma avevate paura di chiedere)))

Uh-huh, geniale.

Queste 17 righe sono in realtà tutto quello che c'è da sapere sulla qualifica di Fedoseev come programmatore.

2019.07.05 15:19:56.309 accesso puntatore non valido in 'test13.mq5' (11,5)

 
Vasiliy Sokolov:

Buon pomeriggio. La memoria del computer ha le stesse prestazioni indipendentemente dal fatto che sia usata in un contesto stack o heap. La gestione dinamica della memoria stessa dipende dall'implementazione del raccoglitore di rifiuti: per esempio, può essere il conteggio dei riferimenti come in Python (variante più lenta) o l'analisi delle epoche di generazione degli oggetti con l'attraversamento del grafico di esecuzione nel processo in background (Net CLR). Quale variante sia usata in MQL è sconosciuta, ma possiamo supporre che sia estremamente efficiente, perché l'utente di MQL5 ha accesso all'operatore di cancellazione direttamente, il che semplifica notevolmente il lavoro del GC stesso. Pertanto, le vostre preoccupazioni circa l'overhead quando si usa new sono infondate - sentitevi liberi di usare la memoria dinamica.

Per quanto riguarda lo "stack overflow", l'unico modo in cui si può incontrare questo caso nei sistemi moderni è quando si usa una ricorsione complessa o si fa un errore nell'algoritmo ricorsivo. Un programma moderno lavora sempre in modalità protetta OC nello spazio di indirizzi virtuale, con caricamento dinamico delle pagine di memoria, quindi non preoccupatevi: lo stack non traboccherà:)

Grazie per la spiegazione intelligente.
Per qualche ragione ho pensato che in mql chiamare sullo stack è più veloce che sull'heap, soprattutto perché non conosciamo l'implementazione del raccoglitore di rifiuti.
Ecco perché ho queste domande, cosa è meglio usare per accelerare la creazione di oggetti, auto o dinamico.
Sì, capisco che tutto dipende dal compito specifico, ma per esempio, prendiamo l'invio di ordini di trading.
E il nostro compito è quello di creare gli oggetti più corretti per una performance di elaborazione rapida.
Abbiamo una classe utente con metodi descritti di richieste commerciali.
Conosciamo il numero di istanze della classe e i suoi metodi.
E come lei suggerisce, "la pila non finirà".

Quindi la mia domanda è: quale metodo è migliore per creare ed eliminare oggetti? Automaticamente o dinamicamente?
Ho avuto un'idea per fare una gestione sintetica degli oggetti automatici in generale.
Cioè, dichiarare oggetti automatici nel corpo della funzione dell'utente.
In questo modo, l'oggetto viene creato sullo stack (in teoria, è più veloce dell'heap). Non dobbiamo preoccuparci della cancellazione automatica dell'oggetto perché la variabile oggetto è dichiarata nella funzione definita dall'utente
e l'oggetto automatico sarà ulteriormente controllato per la distruzione dalla funzione utente stessa, secondo la regola delle variabili dinamiche nelle funzioni.
Ecco perché vorrei ascoltare le opinioni adeguate dei partecipanti di questo ramo, che pensano in questo senso.

 
TheXpert:

Mm-hmm, geniale.

Queste 17 righe sono in realtà tutto quello che c'è da sapere sulle qualifiche di Fedoseev come programmatore.

2019.07.05 15:19:56.309 accesso puntatore non valido in 'test13.mq5' (11,5)

Incredibile. Ed entrambi compilano senza errori (in questo momento) e funziona correttamente.

La prossima volta, disegnate in photoshop.

 
Roman:

Grazie per la spiegazione intelligente.
Per qualche ragione, ho pensato che chiamare sullo stack mql sia più veloce che sull'heap, soprattutto perché non sappiamo come è implementato il raccoglitore di rifiuti.
Ecco perché ho queste domande, cosa è meglio usare per accelerare la creazione di oggetti, auto o dinamico.
Sì, capisco che tutto dipende dal compito specifico, ma per esempio, prendiamo l'invio di ordini di trading.
E il nostro compito è quello di creare gli oggetti più corretti per una performance di elaborazione rapida.
Abbiamo una classe utente con metodi descritti di richieste commerciali.
Conosciamo il numero di istanze della classe e i suoi metodi.
E come lei suggerisce, "la pila non finirà".

Quindi la mia domanda è: quale metodo è migliore per creare ed eliminare oggetti? Automaticamente o dinamicamente?
Ho avuto un'idea per fare una gestione sintetica degli oggetti automatici in generale.
Cioè, dichiarare oggetti automatici nel corpo della funzione dell'utente.
In questo modo, l'oggetto viene creato sullo stack (in teoria, è più veloce dell'heap). Non dobbiamo preoccuparci della cancellazione automatica dell'oggetto perché la variabile oggetto è dichiarata nella funzione definita dall'utente
e l'oggetto automatico sarà ulteriormente controllato per la distruzione dalla funzione utente stessa, secondo la regola delle variabili dinamiche nelle funzioni.
Ecco perché vorrei ascoltare le opinioni adeguate dei partecipanti di questo ramo, che pensano in questo senso.

Hai pensato bene. L'accesso agli oggetti creati con new è molto più lento. E qui non c'è uno spazzino.

 
Igor Makanu:

la realizzazione fisica di queste parole è stata a lungo nascosta agli utenti

imho come questo:

- descrittore - legato al metodo che implementa questa funzionalità nel sistema

- un handle - è tutto uguale a un descrittore, ma il SO lo implementa

- un puntatore e un identificatore implicano che si tratta di un'operazione nella memoria fisica.

E non fa alcuna differenza per noi come funziona.

 

Un consiglio su un'altra questione. Se create una classe figlia CMyButton da CButton, potete creare un pulsante e poi cambiare le sue proprietà al di fuori della classe. Di seguito questo viene fatto in OnInit().

Ma se voglio fare campi aggiuntivi all'interno della classe figlio e usare le proprietà incorporate della classe CButton in nuove funzioni, come può essere implementato correttamente?

Nella classe CButton, il membro di classe m_button è dichiarato nella sezione privata.

#include <Controls\Button.mqh>

class CMyButton : public CButton
{ 
  private: 

  public: 
              CMyButton(void){}; 
             ~CMyButton(void){}; 
             
        bool    isPrevState;        // состояние кнопки на предыд.тике, true - была нажата     
        void    setButton();        // создаем кнопку
        void    setProp();          // задаем в ходе программы свойства
}; 

void CMyButton::setButton(void)
{
  // как в этой функции создать кнопку? Я не могу вызвать метод Create()
}

//+------------------------------------------------------------------------------------------------------------------+
//| 
//+------------------------------------------------------------------------------------------------------------------+

CButton Btn;
CMyButton MyBtn;

int OnInit()
  {
  
   Btn.Create(0, "Btn", 0, 50, 50, 120, 75);
   Btn.Text("Standart");
   MyBtn.Create(0, "MyBtn", 0, 50, 200, 150, 225);
   MyBtn.Text("MyBtn");
   
   return(INIT_SUCCEEDED);
  }
 
Dmitry Fedoseev:

Sì, cancella e scrive un messaggio sulle perdite di memoria, solo perché i programmatori che scrivono gli EA non si annoino a morte.

È interessante come ieri c'era una perdita di memoria e oggi non ce ne può essere nemmeno una.

E a proposito di uccelli... i descrittori sono anche puntatori. E sapete, la parola stessa non cambia nulla, che sia un descrittore, un puntatore, un identificatore.

La perdita proviene dallo spazio degli indirizzi del processo. Quando si perde in un ciclo while(true), il programma alla fine andrà in crash alla prossima allocazione di memoria dall'heap, che si è esaurito.
 
Dmitry Fedoseev:

Ed entrambi compilano senza errori (in questo momento) e funziona correttamente.

Sì, già due persone non correlate stanno photoshoppando il crash del tuo codice)

Il tuo codice non può funzionare correttamente, è ovvio dal codice stesso ))

 
TheXpert:

Sì, due persone non collegate stanno già photoshoppando il tuo codice)

Il tuo codice non può funzionare correttamente, è ovvio dal codice stesso ))

Proprio ora, volevo scrivere la stessa cosa))))