Preguntas sobre POO en MQL5 - página 3

 

Si todos los botones funcionan con una sola línea a la vez, entonces cree una variable estática en la clase del botón para hacer referencia a la línea. Pero sólo esto no es razonable, porque limita las posibilidades de la clase de botones - no puedes crear dos pares de botones para trabajar con dos líneas en paralelo.

Y la solución correcta al problema es elemental - escribir una función, la referencia a la línea se pasa a la función, y la función pasa esta referencia a los objetos botón deseados. No es necesario buscar ninguna maravilla en OOP.

O bien, puede escribir una clase que cree dos botones.

 
Dmitry Fedoseev:

Si todos los botones funcionan con una sola línea a la vez, entonces cree una variable estática en la clase del botón para hacer referencia a la línea. Pero eso por sí solo no tiene sentido, porque limita lo que la clase botón puede hacer: no puedes crear dos pares de botones para trabajar con dos líneas en paralelo.

Sí, tengo cuatro pares de botones y cuatro líneas, por lo que también descarté la variable estática como opción.

Y la solución correcta al problema es elemental: escribir una función, el enlace a la línea se pasa a la función, y este enlace se pasa a los objetos botón deseados en la función. No es necesario buscar ningún milagro en la OOP.

Bueno, o escribir una clase que crea dos botones.

Y yo creía en los milagros de la OOP ).

Gracias por estas opciones, pensaré cuál me conviene más.

 
Vasiliy Pushkaryov:

Ayúdame a resolver un problema. Hay dos botones y una línea. Un botón, cuando se pulsa, pone la línea en modo de edición, y cuando se suelta, borra la línea. El segundo botón, al ser pulsado, fija la línea, y al ser pulsado, la devuelve al modo de edición. Cada botón puede cambiar el color y algunas otras propiedades del objeto Línea. El objeto "Línea" se define globalmente. ¿Es posible pasar una referencia al objeto "Línea" a cada botón inmediatamente después de crear los botones, de manera que cuando se manipule la variable de referencia dentro de los objetos "Botón", todos los cambios se recuerden en el objeto global "Línea"?

He esbozado un script simplificado a continuación, en lugar de pulsar un botón - función addition(), que incrementa el contador del objeto "Line". Entiendo que se puede pasar el objeto "Línea" como argumento de una función por referencia, pero justo en la versión de trabajo, hay varias funciones de este tipo, por lo que me gustaría pasar la referencia al principio una vez. Es decir, ¿es posible hacer que Btn1.addition() o Btn2.addition() aumenten el gLine.count?

Así es como lo estoy haciendo ahora:


¿tal vez esta sea la forma de hacerlo?

//+------------------------------------------------------------------+
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:

¿tal vez así es como debería ser?

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, eso es, muchas gracias.

Todavía estoy "chapoteando" en los punteros, por lo que tu solución me ayudará en mi tarea actual y a entender mejor cómousar los punteros.

Gracias por sus comentarios.

 
Igor Makanu:

¿tal vez así es como debería ser?

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

¿Y por qué usas GetPointer(gLine) si tú mismo declaraste gLine como un puntero? )))

También es necesario crear el objeto CLine al declararlo:

CLine* gLine=nuevo CLine;

El botón y la línea también necesitan ser inicializados en la etapa de inicialización del botón.

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

¿Por qué usas GetPointer(gLine) si tú mismo declaraste gLine como un puntero? )))

La formación de un objeto CLine también es una tarea urgente a la hora de declararlo:

CLine* gLine=nuevo CLine;

El botón y la línea también deben ser inicializados en la etapa de inicialización del botón.

Era de noche, no está claro por qué lo escribí así... En realidad estaba durmiendo, el Skype de mi teléfono me ha despertado, así que me he pasado por el foro )))

Y en serio, mi ejemplo es un tutorial, no lo he comprobado, quizás me he reasegurado a nivel subconsciente, no entiendo del todo lo que es un puntero MQL, obviamente no funciona como en los punteros de C++

He estado tratando de entenderlo, pero no he descubierto cómo funcionan los punteros como parámetro para la funciónhttps://www.mql5.com/ru/forum/1111/page2470#comment_11796309- paso un puntero a la función allí, pero de hecho obtengo una nueva copia del puntero creado

SZY: No consigo averiguar qué alcance tienen los punteros MQL, también he preguntado ahttps://www.mql5.com/ru/forum/1111/page2488#comment_12154218.... Parece que no entiendo qué casos tienen alcance local y cuáles tienen alcance global... Así que estoy trabajando con punteros MQL mediante un experimento científico (((


Vasiliy Pushkaryov:

Sí, Igor, eso es, muchas gracias.

Todavía estoy "nadando" en punteros, por eso tu solución me será muy útil para mi tarea actual y para seguir entendiendo cómo usar los punteros.

Gracias por sus comentarios.

Por favor, con los punteros MQL sólo la práctica ayudará aquí, tienen un comportamiento peculiar, como escribió@Vladimir Simakov su problema es más probable que se resuelva escribiendo un constructor con parámetro - yo suelo hacerlo, desde el punto de vista abstracto? - No es correcto, pero es conveniente y siempre funciona correctamente - y el compilador no dejará que se olvide de enlazar el puntero.

if(CheckPointer(m_Line)==POINTER_DYNAMIC)

esta comprobación puede eliminarse porque de todos modos se guardará el puntero al llamar al constructor

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

Vaya, resulta que la tarea no era esperar a que dos objetos pasaran un puntero a una línea al mismo tiempo. En realidad se trataba de pasar un puntero. ¿Quién lo hubiera pensado?

No es necesario crear el objeto a través de new para poder pasar un puntero a alguna parte. Pero la clase a la que se pasa el puntero debe tener una variable puntero (con un asterisco *).

 
Igor Makanu:

era de noche, está oscuro - por eso lo escribí así... En realidad estaba durmiendo, el Skype de mi teléfono me despertó, así que hojeé el foro de pasada )))

Y en serio, mi ejemplo es un tutorial, no lo he comprobado, quizás me he reasegurado a nivel subconsciente, no entiendo del todo lo que es un puntero MQL, obviamente no funciona como en los punteros de C++

He estado tratando de entenderlo, pero no he descubierto cómo funcionan los punteros como parámetro para la funciónhttps://www.mql5.com/ru/forum/1111/page2470#comment_11796309- Paso un puntero a la función allí, pero de hecho obtengo una nueva copia del puntero creado

SZY: No puedo averiguar qué alcance tienen los punteros MQL, también pregunté ahttps://www.mql5.com/ru/forum/1111/page2488#comment_12154218.... Todavía no entiendo qué casos tienen alcance local y cuáles tienen alcance global... En definitiva, estoy trabajando con punteros MQL utilizando el método del experimento científico (((

Todo es sencillo en el primer caso. En realidad, se crea un nuevo objeto dinámico en la pila, y eso es todo. Tienes que pasarlo a la ...(CObj* &jbj,...

Y en el segundo caso, hay que hacerlo:

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

Para el primer caso, es sencillo. En realidad se crea un nuevo objeto dinámico en la pila y ya está. Deberías pasarlo a la ...(CObj* &jbj,...

Y en el segundo caso debería hacerlo:

Lo comprobaré esta noche, la referencia no da mucha información sobre el uso de &.

Gracias.

 
El puntero también se puede pasar por no-referencia - sin &.