Preguntas sobre POO en MQL5 - página 11

 
Dmitry Fedoseev:

Y hablando de pájaros, los descriptores también son punteros. Y ya sabes, nada cambia de la palabra en sí, ya sea un descriptor, un puntero, un identificador.

la aplicación física de estas palabras se ha ocultado durante mucho tiempo a los usuarios

En mi opinión, es más o menos así

- descriptor - está vinculado al método que implementa esta funcionalidad en el sistema

- un handle - todo es igual que un descriptor, pero el SO lo implementa

- un puntero y un identificador están pensados para trabajar con la memoria física

 
Dmitry Fedoseev:

Y si tienes que pasar un puntero a una función para crear un objeto en la función, así es como funciona:

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

CObj * obj;

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

void z(CObj & o){
   o = new CObj();
}
En realidad, eso es todo lo que querías saber sobre la OOP, pero tenías miedo de preguntar))

Ajá, genio.

Estas 17 líneas son en realidad todo lo que hay que saber sobre la cualificación de Fedoseev como programador.

2019.07.05 15:19:56.309 acceso de puntero no válido en 'test13.mq5' (11,5)

 
Vasiliy Sokolov:

Buenas tardes. La memoria del ordenador tiene el mismo rendimiento independientemente de si se utiliza en un contexto de pila o de montón. La gestión de la memoria dinámica en sí misma depende de la implementación del recolector de basura: por ejemplo, puede ser el recuento de referencias como en Python (variante más lenta) o el análisis de las épocas de generación de objetos con el recorrido del gráfico de ejecución en el proceso de fondo (Net CLR). Se desconoce qué variante se utiliza en MQL, pero podemos suponer que es extremadamente eficiente, porque el usuario de MQL5 tiene el operador de borrado directamente disponible, lo que simplifica enormemente el trabajo de la propia GC. Por lo tanto, su preocupación por la sobrecarga al usar new es infundada - siéntase libre de usar la memoria dinámica.

En cuanto al "desbordamiento de la pila", la única forma de encontrar este caso en los sistemas modernos es cuando se utiliza una recursión compleja o se comete un error en el algoritmo recursivo. Un programa moderno siempre trabaja en modo protegido por OC en el espacio de direcciones virtual, con carga dinámica de páginas de memoria, así que no te preocupes: la pila no se desbordará:)

Gracias por la inteligente explicación.
Por alguna razón pensé que en mql llamar en la pila es más rápido que en el heap, sobre todo porque no conocemos la implementación del recolector de basura.
Por eso tengo esas dudas, qué es mejor usar para acelerar la creación de objetos, auto o dinámico.
Sí, entiendo que todo depende de la tarea específica, pero por ejemplo, tomemos el envío de solicitudes de comercio.
Y nuestra tarea consiste en crear los objetos más correctos para un rendimiento de procesamiento rápido.
Tenemos una clase de usuario con métodos descritos de solicitudes comerciales.
Conocemos el número de instancias de la clase y sus métodos.
Y como sugieres, "la pila no se acabará".

De ahí que mi pregunta sea: ¿qué método es mejor para crear y eliminar objetos? ¿Automática o dinámicamente?
Tuve la idea de hacer una gestión sintética de los objetos automáticos en general.
Es decir, declarar los objetos automáticos en el cuerpo de la función del usuario.
De esta manera, el objeto se crea en la pila (en teoría, es más rápido que el montón). No tenemos que preocuparnos por el borrado automático del objeto porque la variable del objeto se declara en la función definida por el usuario
y el objeto automático será comprobado adicionalmente para su destrucción por la propia función del usuario, según la regla de las variables dinámicas en las funciones.
Por eso me gustaría escuchar las opiniones adecuadas de los participantes de esta rama, que piensan en este sentido.

 
TheXpert:

Mm-hmm, genio.

Esas 17 líneas son, en realidad, todo lo que hay que saber sobre las calificaciones de Fedoseev como programador.

2019.07.05 15:19:56.309 acceso de puntero no válido en 'test13.mq5' (11,5)

Increíble. Y ambos compilan sin errores (ahora mismo) y funciona correctamente.

La próxima vez, dibuja en photoshop.

 
Roman:

Gracias por la inteligente explicación.
Por alguna razón, pensé que llamar en la pila de mql es más rápido que en el montón, sobre todo porque no sabemos cómo se implementa el recolector de basura.
Por eso tengo esas dudas, qué es mejor usar para acelerar la creación de objetos, auto o dinámico.
Sí, entiendo que todo depende de la tarea específica, pero por ejemplo, tomemos el envío de solicitudes de comercio.
Y nuestra tarea consiste en crear los objetos más correctos para un rendimiento de procesamiento rápido.
Tenemos una clase definida por el usuario con métodos descritos de solicitudes comerciales.
Conocemos el número de instancias de la clase y sus métodos.
Y como sugieres, "la pila no se acabará".

De ahí que mi pregunta sea: ¿qué método es mejor para crear y eliminar objetos? ¿Automática o dinámicamente?
Tuve la idea de hacer una gestión sintética de los objetos automáticos en general.
Es decir, declarar los objetos automáticos en el cuerpo de la función del usuario.
De este modo, el objeto se crea en la pila (en teoría, es más rápido que el montón). No tenemos que preocuparnos por el borrado automático del objeto porque la variable del objeto se declara en la función definida por el usuario
y el objeto automático será comprobado adicionalmente para su destrucción por la propia función del usuario, según la regla de las variables dinámicas en las funciones.
Por eso me gustaría escuchar las opiniones adecuadas de los participantes de esta rama, que piensan en este sentido.

Has pensado bien. El acceso a los objetos creados con new es mucho más lento. Y aquí no hay ningún recolector de basura.

 
Igor Makanu:

la aplicación física de estas palabras se ha ocultado durante mucho tiempo a los usuarios

imho así:

- descriptor - vinculado al método que implementa esta funcionalidad en el sistema

- un handle - todo es igual que un descriptor, pero el SO lo implementa

- un puntero y un identificador implican que se trata de una operación en memoria física.

Y nos da igual cómo funcione.

 

Un consejo sobre otra cuestión. Si creas una clase hija CMyButton a partir de CButton, puedes crear un botón y luego cambiar sus propiedades fuera de la clase. A continuación esto se hace en OnInit().

Pero si quiero hacer campos adicionales dentro de la clase hija y utilizar las propiedades incorporadas de la clase CButton en nuevas funciones, ¿cómo se puede implementar esto correctamente?

En la clase CButton, el miembro de la clase m_button se declara en la sección privada.

#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í, borra y escribe un mensaje sobre las fugas de memoria, sólo para que los programadores que escriben EAs no se aburran de su vida.

Es interesante como ayer había una fuga de memoria y hoy no puede haberla.

Y hablando de pájaros... los descriptores también son punteros. Y ya sabes, la palabra en sí no cambia nada, ya sea un descriptor, un puntero, un identificador.

La fuga proviene del espacio de direcciones del proceso. Cuando se produce una fuga en el bucle while(true), el programa acabará fallando en la siguiente asignación de memoria del montón, que se ha agotado.
 
Dmitry Fedoseev:

Y ambos compilan sin errores (ahora mismo) y funciona correctamente.

Sip, ya hay dos personas no relacionadas que están photoshopeando la caída de tu código )

Tu código no puede funcionar correctamente, es obvio por el propio código ))

 
TheXpert:

Sip, dos personas no relacionadas ya están photoshopeando tu código )

Tu código no puede funcionar correctamente, es obvio por el propio código ))

Justo ahora, quería escribir lo mismo))))