Ayuda con la POO - página 3

 
Vasiliy Sokolov #:

DE ACUERDO. No lo entiendo. ¿Lo entiendes? ¿Seguro que lo entiendes? ¿Exactamente?

El argumento se reduce a la siguiente afirmación:

...

No se trataba de una discusión general, sino de una situación relativa a un solo puesto, y expliqué cuál era el problema. Bien, no hubo ninguna catástrofe.

 

Matriz declarada doble x[268435448];

La misma matriz en la función OnStart().

También se hizo una llamada recursiva con profundidad LONG_MAX.

No hay problemas.

 
fxsaber #:

¿No utilizas matrices estáticas?

grande. si el tamaño de la matriz es pequeño, constante y conocido de antemano, la estática es mejor y probablemente más rápida.

 
Andrei Trukhanovich #:

grande. si el tamaño de la matriz es pequeño, constante y conocido de antemano, la estática es mejor y probablemente más rápida.

Me gustaría tener una forma de obtener una lista de variables/arreglos estáticos y sus tamaños. Probablemente se necesite un analizador de código como el que se hace aquí.

Supongo que un array estático de cadenas y un array doble son cosas muy diferentes.

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 #:

Supongo que las matrices estáticas de cadenas y las matrices dobles son cosas muy diferentes.

string es esencialmente una clase interna que consiste en un puntero y un tamaño int, es decir, para la matriz doble ocupará condicionalmente 1,5 veces menos espacio

No creo que tenga mucho sentido molestarse en ello, a no ser que tengas arrays estáticos con millones de elementos.

 
fxsaber #:

¿No utilizar matrices estáticas?

Así que hay esencialmente cuatro tipos de datos en MQL:

  • Datos estáticos y predefinidos. Se incorpora al programa en tiempo de compilación y ya no se modifica. Se encuentran en un espacio de memoria privado. Por ejemplo, son matrices estáticas de tipo char[1024].
  • Datos gestionados manualmente a través de los punteros. Son instancias de clases pero definidas por puntero, por ejemplo CFoo* bar donde bar es una instancia de CFoo. Estas instancias son de tipo POINTER_DYNAMIC. Este tipo de almacenamiento es el más problemático, aunque no es necesario en la mayoría de los casos.
  • Datos gestionados por el recolector de basura de la máquina virtual mql en la que se ejecuta el programa. Esto incluye las instancias de las clases. El puntero a un objeto de este tipo será POINTER_AUTOMATIC. Estos objetos se encuentran en el heap de esta máquina virtual o en la sección privada. El modo exacto depende de los datos y su tamaño, aparentemente, y de lo que tengan los desarrolladores. Esta información no está disponible. Estos datos incluyen, por ejemplo, las clases de usuarios. Cualquier definición de una instancia de clase sin puntero define este tipo de almacenamiento. Por ejemplo CFoo bar define una instancia de la clase CFoo bar, cuyo puntero no necesita ser liberado. La máquina virtual realiza todas las operaciones de liberación. No es necesario utilizar el operador de borrado y, por lo tanto, se enfrenta al problema de los objetos filtrados.
  • Datos situados en la pila. Son, en primer lugar, variables locales de las funciones. Es decir, cuando escribimos int a = 5 dentro de cualquier función, la parte superior de la pila se mueve 4 bytes hacia arriba, asignando así el tamaño de memoria necesario. Tal vez, en MQL, los tipos almacenados en la pila incluyen también estructuras (nunca lo he comprobado, para ser sincero). Estos datos no ocupan mucho lugar, e incluso teniendo en cuenta una cadena de llamadas de funciones anidadas, la pila en su conjunto requiere mucha menos memoria que un montón. Este tipo de almacenamiento se utiliza automáticamente, no hay que pensar en ello.

Si dejamos la pila para las funciones y sus variables locales, nos quedan tres tipos con los que trabajar. Personalmente creo (y es sólo mi opinión) que los datos definidos con vida automática combinan bien las ventajas de los dos tipos anteriores, sin sus desventajas. Los datos definidos con puntero automático son tan predecibles y seguros como los estáticos, pero tan flexibles como los dinámicos, controlados manualmente. Por previsibilidad me refiero a escenarios en los que no es necesario hacer comprobaciones adicionales de bits de puntero y preguntarse si alguien ya ha borrado los datos antes. Por flexibilidad me refiero a escenarios en los que se puede trabajar con datos referenciados por un autopuntero como con un puntero normal, pasando el puntero a una función o, para los arrays, reciclándolo.

Para ilustrar lo que acabo de decir, puedes comparar el código inicial proporcionado por Ihor Herasko y el mismo código que he escrito para POINTER_AUTOMATIC. No hay comprobaciones ni inicializaciones adicionales, ni el operador borra 60 000 000 veces. Todo esto le ahorra tiempo, esfuerzo y, lo que también es importante, recursos. Si lo entiendes, casi nunca necesitarás trabajar con punteros. Siempre se puede escribir un algoritmo de este tipo que minimice este trabajo o que no lo haga. Por ejemplo, nunca manejo objetos manualmente en mi código - simplemente no hay necesidad de hacerlo. En cuanto a las matrices estáticas, entonces a veces tengo que utilizar, por ejemplo, para coser en el programa de los datos que necesita, pero son cosas tan especiales, que los usuarios comunes, supongo, no los necesitan. Lo mejor es utilizar colecciones ya hechas como CArrayObj, o las propias. Ahora las plantillas y las capacidades MQL permiten crear cosas bastante flexibles que son mucho mejores que las matrices estáticas.

 
No hay recolector de basura en el emcool.
 

Vasiliy Sokolov #:

Datos estáticos y predefinidos. Se incorpora al programa en tiempo de compilación y ya no se modifica. Se almacenan en una zona de memoria privada. Por ejemplo, son matrices estáticas como char[1024].

Si el array no está inicializado,

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

¿por qué debería estar escrito en EX5?

 
fxsaber #:

Si el array no está inicializado,

¿por qué habría que coserlo en la EX5?

Sí, es cierto, los no inicializados no se cosen, por supuesto. Los inicializados sí. Pero los tamaños de ambos tipos se definen en el momento de la compilación y ya no cambian. Es decir, las matrices estáticas pueden dividirse condicionalmente en dos grupos.

 
Dmitry Fedoseev #:
En emcool no hay ningún recolector de basura.

Oficialmente, sí. Extraoficialmente, muchas cosas indican que existe:

  • No hay punteros en MQL. En cambio, son sustituidos por algo que se parece mucho a ellos.
  • En MQL no hay asignación directa de memoria, como en C por ejemplo;
  • Los programas en MQL son ejecutados por una determinada máquina virtual. Renat escribió sobre ello brevemente y ni una sola vez;
  • La instancia de la clase puede ser definida y luego será liberada automáticamente. Por lo tanto, hay algún mecanismo que supervisa estas instancias y las libera cuando es necesario. ¿Qué es eso sino un recolector de basura?
  • Cualquier instancia inicializada a través de un puntero y no liberada adecuadamente será marcada como objeto filtrado al salir. Se imprimirá su número y el tamaño total de la memoria perdida. Un programa con fugas de memoria ni siquiera será validado en Market. De este modo, todos los objetos, incluso los asignados manualmente, se contabilizan, se conocen y son conocidos por el sistema. Esta es una de las tareas clásicas que resuelve el recolector de basura.