Domande su OOP in MQL5 - pagina 3

 

Se tutti i pulsanti lavorano con una sola linea alla volta, allora create una variabile statica nella classe del pulsante per fare riferimento alla linea. Ma solo questo non è ragionevole, perché limita le possibilità della classe dei pulsanti - non si possono creare due coppie di pulsanti per lavorare con due linee in parallelo.

E la soluzione corretta al problema è elementare - scrivere una funzione, il riferimento alla linea viene passato alla funzione, e la funzione passa questo riferimento agli oggetti pulsante desiderati. Non c'è bisogno di cercare meraviglie in OOP.

Oppure, potete scrivere una classe che crea due pulsanti.

 
Dmitry Fedoseev:

Se tutti i pulsanti lavorano con una sola linea alla volta, allora create una variabile statica nella classe del pulsante per fare riferimento alla linea. Ma questo da solo non ha senso, perché limita ciò che la classe dei pulsanti può fare - non si possono creare due coppie di pulsanti per lavorare con due linee in parallelo.

Sì, ho quattro coppie di pulsanti e quattro linee, quindi ho scartato anche la variabile statica come opzione.

E la soluzione corretta al problema è elementare: scrivere una funzione, il link alla linea viene passato alla funzione, e questo link viene passato agli oggetti pulsante desiderati nella funzione. Non c'è bisogno di cercare miracoli in OOP.

Bene, o scrivere una classe che crei due pulsanti.

E credevo nei miracoli di OOP ).

Grazie per queste opzioni, penserò a quale mi conviene di più.

 
Vasiliy Pushkaryov:

Aiutami a risolvere un problema. Ci sono due pulsanti e una linea. Un pulsante, quando viene premuto, mette la linea in modalità di modifica, e quando viene rilasciato, cancella la linea. Il secondo pulsante, quando viene cliccato, fissa la linea, e quando viene cliccato, la rimette in modalità di modifica. Ogni pulsante può cambiare il colore e alcune altre proprietà dell'oggetto Line. L'oggetto "Linea" è definito globalmente. È possibile passare un riferimento all'oggetto "Linea" ad ogni pulsante subito dopo aver creato i pulsanti in modo che quando si manipola la variabile di riferimento all'interno degli oggetti "Button", tutti i cambiamenti sono ricordati nell'oggetto globale "Linea".

Ho abbozzato uno script semplificato qui sotto, invece di premere un pulsante - funzione addition(), che incrementa il contatore dell'oggetto "Line". Capisco che si possa passare l'oggetto "Line" come argomento di una funzione per riferimento, ma proprio nella versione di lavoro, ci sono diverse funzioni di questo tipo, quindi vorrei passare il riferimento all'inizio una sola volta. Cioè è possibile fare in modo che Btn1.addition() o Btn2.addition() aumentino il gLine.count?

È così che sto facendo adesso:


forse questo è il modo per farlo?

//+------------------------------------------------------------------+
class CLine
  {
public:
   int               count;
                     CLine(void){count=0;};
                    ~CLine(void){};
  };
//+------------------------------------------------------------------+
class CMyButton
  {
private:
public:
   CLine            *m_Line;
                     CMyButton(void):m_Line(NULL){};
                    ~CMyButton(void){};

   void bind(CLine *aLine) {m_Line=aLine;}
   void addition() {if(CheckPointer(m_Line)==POINTER_DYNAMIC){++m_Line.count;}}
  };


CMyButton  Btn1;
CMyButton  Btn2;

CLine *gLine;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   gLine = new CLine;
   Btn1.bind(GetPointer(gLine));
   Btn2.bind(GetPointer(gLine));
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   Print("Line.count=", gLine.count);
   Btn1.addition();
   Print("Line.count=", gLine.count, "  Btn1.m_Line.count=", Btn1.m_Line.count);
   Btn2.addition();
   Print("Line.count=", gLine.count, "  Btn2.m_Line.count=", Btn2.m_Line.count);
   Btn1.addition();
   Print("Line.count=", gLine.count, "  Btn1.m_Line.count=", Btn1.m_Line.count);
   Btn2.addition();
   Print("Line.count=", gLine.count, "  Btn2.m_Line.count=", Btn2.m_Line.count);
  }
//+------------------------------------------------------------------+

2019.07.04 00:44:30.464 1 (EURUSD,H1) Line.count=196

2019.07.04 00:44:30.464 1 (EURUSD,H1) Line.count=197 Btn1.m_Line.count=197

2019.07.04 00:44:30.464 1 (EURUSD,H1) Line.count=198 Btn2.m_Line.count=198

2019.07.04 00:44:30.464 1 (EURUSD,H1) Line.count=199 Btn1.m_Line.count=199

2019.07.04 00:44:30.464 1 (EURUSD,H1) Line.count=200 Btn2.m_Line.count=200

2019.07.04 00:44:31.856 1 (EURUSD,H1) Line.count=200

2019.07.04 00:44:31.856 1 (EURUSD,H1) Line.count=201 Btn1.m_Line.count=201

 
Igor Makanu:

forse è così che dovrebbe essere?

2019.07.04 00:44:30.464 1 (EURUSD,H1) Line.count=196

2019.07.04 00:44:30.464 1 (EURUSD,H1) Line.count=197 Btn1.m_Line.count=197

2019.07.04 00:44:30.464 1 (EURUSD,H1) Line.count=198 Btn2.m_Line.count=198

2019.07.04 00:44:30.464 1 (EURUSD,H1) Line.count=199 Btn1.m_Line.count=199

2019.07.04 00:44:30.464 1 (EURUSD,H1) Line.count=200 Btn2.m_Line.count=200

2019.07.04 00:44:31.856 1 (EURUSD,H1) Line.count=200

2019.07.04 00:44:31.856 1 (EURUSD,H1) Line.count=201 Btn1.m_Line.count=201

Sì Igor, è tutto, grazie mille.

Sto ancora "annaspando" nei puntatori, quindi la tua soluzione mi aiuterà nel mio compito attuale e nel capire ulteriormente comeusare i puntatori.

Grazie per il vostro feedback.

 
Igor Makanu:

forse è così che dovrebbe essere?

2019.07.04 00:44:30.464 1 (EURUSD,H1) Line.count=196

2019.07.04 00:44:30.464 1 (EURUSD,H1) Line.count=197 Btn1.m_Line.count=197

2019.07.04 00:44:30.464 1 (EURUSD,H1) Line.count=198 Btn2.m_Line.count=198

2019.07.04 00:44:30.464 1 (EURUSD,H1) Line.count=199 Btn1.m_Line.count=199

2019.07.04 00:44:30.464 1 (EURUSD,H1) Line.count=200 Btn2.m_Line.count=200

2019.07.04 00:44:31.856 1 (EURUSD,H1) Line.count=200

2019.07.04 00:44:31.856 1 (EURUSD,H1) Line.count=201 Btn1.m_Line.count=201

E perché usate GetPointer(gLine) se voi stessi avete dichiarato gLine come puntatore? )))

Bisogna anche creare l'oggetto CLine quando lo si dichiara:

CLine* gLine=nuovo CLine;

Anche il pulsante e la linea devono essere inizializzati nella fase di inizializzazione del pulsante.

...
                CMyButton(CLine* line):m_Line(!CheckPointer(line)?NULL:line){};
...
CLine* gLine=new CLine;
CMyButton  Btn1(gLine);
 
Vladimir Simakov:

Perché usate GetPointer(gLine) se voi stessi avete dichiarato gLine come puntatore? )))

Formare un oggetto CLine è anche un compito urgente quando lo si dichiara:

CLine* gLine=nuovo CLine;

Anche il pulsante e la linea devono essere inizializzati nella fase di inizializzazione del pulsante.

Era di notte, non è chiaro perché l'ho scritto così... In realtà stavo dormendo, Skype sul mio telefono mi ha svegliato, quindi ho solo saltato il forum )))

E seriamente, il mio esempio è un tutorial, non l'ho controllato, forse ho assicurato troppo a livello inconscio, non ho capito bene cos'è un puntatore MQL, ovviamente non funziona come nei puntatori C++

Ho cercato di capirlo, ma non ho capito come funzionano i puntatori come parametro per la funzionehttps://www.mql5.com/ru/forum/1111/page2470#comment_11796309- passo un puntatore alla funzione lì, ma in realtà ottengo una nuova copia del puntatore creato

SZY: non riesco a capire che portata hanno i puntatori MQL, ho anche chiesto ahttps://www.mql5.com/ru/forum/1111/page2488#comment_12154218.... Non mi sembra di capire quali casi hanno portata locale e quali hanno portata globale ... Quindi sto lavorando con i puntatori MQL per esperimento scientifico (((


Vasiliy Pushkaryov:

Sì, Igor, è tutto, grazie mille.

Sto ancora "nuotando" nei puntatori, ecco perché la tua soluzione sarà molto utile per me nel mio compito attuale e per capire ulteriormente come usare i puntatori.

Grazie per il vostro feedback.

Con i puntatori MQL solo la pratica aiuterà qui, hanno un comportamento particolare, come ha scritto@Vladimir Simakov il tuo problema è più probabile che sia risolto scrivendo un costruttore con parametro - di solito lo faccio, dal punto di vista astratto? - Non è corretto, ma è conveniente e funziona sempre correttamente - e il compilatore non vi lascerà dimenticare di legare il puntatore.

se(CheckPointer(m_Line)==POINTER_DYNAMIC)

questo controllo può essere eliminato perché si salverà comunque il puntatore quando si chiama il costruttore

Ошибки, баги, вопросы
Ошибки, баги, вопросы
  • 2019.05.22
  • www.mql5.com
Общее обсуждение: Ошибки, баги, вопросы
 

Wow, si scopre che il compito non era quello di aspettare che due oggetti passassero un puntatore a una linea allo stesso tempo. In realtà si trattava di passare un puntatore. Chi l'avrebbe mai detto?

Non è necessario creare l'oggetto tramite new per poter passare un puntatore da qualche parte. Ma la classe a cui viene passato il puntatore deve avere una variabile puntatore (con un asterisco *).

 
Igor Makanu:

era di notte, è buio - perché l'ho scritto così... In realtà stavo dormendo, Skype sul mio telefono mi ha svegliato, quindi ho sfiorato il forum di sfuggita )))

E seriamente, il mio esempio è un tutorial, non l'ho controllato, forse ho controllato troppo a livello inconscio, non ho capito bene cos'è un puntatore MQL, ovviamente non funziona come nei puntatori C++

Ho cercato di capirlo, ma non ho capito come funzionano i puntatori come parametro per la funzionehttps://www.mql5.com/ru/forum/1111/page2470#comment_11796309- passo un puntatore alla funzione lì, ma in realtà ottengo una nuova copia del puntatore creato

SZY: non riesco a capire che portata hanno i puntatori MQL, ho anche chiesto ahttps://www.mql5.com/ru/forum/1111/page2488#comment_12154218.... Non ho ancora capito quando un puntatore ha un ambito locale e quale ha un ambito globale ... Tutto sommato, sto lavorando con MQL-pointers usando il metodo dell'esperimento scientifico (((

Tutto è semplice nel primo caso. In realtà si crea un nuovo oggetto dinamico sullo stack, e questo è tutto. Dovete passarlo nel ...(CObj* &jbj,...

E nel secondo caso, devi farlo:

void  AddValue (T &value)  { Tptr  = value; mlist.Add(Tptr);       }
 
Vladimir Simakov:

Per il primo caso, è semplice. In realtà si crea un nuovo oggetto dinamico sullo stack e questo è tutto. Dovreste passarlo nel ...(CObj* &jbj,...

E nel secondo caso si dovrebbe:

Lo controllerò stasera, il riferimento non dà molte informazioni sull'uso di &.

Grazie!

 
Il puntatore può anche essere passato per non riferimento - senza &.
Motivazione: