Preguntas de los principiantes MQL5 MT5 MetaTrader 5 - página 192

 

He empezado a aprender OOP y no puedo superar el siguiente obstáculo. El siguiente script es un ejemplo:

CSum result;
void OnStart()
  {
//---
  }
//+----------------------------------------+
class CSum
  {
public:
   int               Calculate(int A,int B);
  };
//---
int CSum::Calculate(int A,int B)
  {
   return(A+B);
  }

Sin la línea "CSum result;", el compilador no generará un error. Pero provoca un error:

Dime qué pasa. Parece que he declarado el objeto de clase correctamente.

 
paladin800:

He empezado a aprender OOP y no puedo superar el siguiente obstáculo. El siguiente script es un ejemplo:

Sin la línea "CSum result;", el compilador no generará un error. Pero provoca un error:

Por favor, dime qué pasa. Parece que he declarado el objeto de clase correctamente.

Una variable del tipo CSum (resultado) se declara antes de que se haga la descripción de CSum, lo que significa que el compilador no conoce todavía este tipo. Inserte CSum al principio del archivo.
 
Lone_Irbis:
Además, ¿hasta qué punto puede/debe explotarse el sistema de variables globales? ¿Es posible sobrecargar algo de esta manera, o hay un límite? Por ejemplo, digamos que dos o más centenares de variables (de las cuales aproximadamente la mitad se convierten en entrada y vuelta, según el fragmento de código que requiera la prueba) y una docena y media de pequeñas matrices a nivel global, ¿es mucho o poco? ^^' ¿Y qué pasa si hay dos o tres veces más al afinar el sistema? Y si no hay que complicarse tanto, ¿hay alguna forma más sencilla de gestionar el intercambio de datos entre una docena de subsistemas diferentes, muchos de los cuales necesitan los resultados de los demás?
No, no lo hay. Las variables globales se utilizan para otros fines. Utilizar las clases para describir los subsistemas. Y será mejor que evites por completo el uso de arrays y variables globales.
 
C-4:
Una variable de tipo CSum (resultado) - se declara antes de hacer la descripción de CSum, lo que significa que el compilador no conoce todavía este tipo. Inserte CSum al principio del archivo.
Oops, funcionó. Pongo la clase al final del código por analogía con la colocación de las funciones. No esperaba que para una clase tal ordenamiento hiciera la diferencia.
 
paladin800:
Oops, funcionó. Pongo la clase al final del código, de forma similar a la colocación de las funciones. No esperaba que esa ordenación fuera a suponer una diferencia para la clase.
Sí, desgraciadamente el orden de precedencia es importante. El caso más difícil es cuando dos clases se utilizan simultáneamente. Sea cual sea la clase que introduzcamos primero, la segunda clase será desconocida para el compilador y generará un error. En este caso no se puede prescindir de la declaración de la clase. En su caso, es mejor separar CSum en un archivo separado, por ejemplo Sum.mqh e incluirlo usando el dictado #include "Sum.mqh".
 
C-4:
No, no deberías. Las variables globales se utilizan para otros fines. Utilizar las clases para describir los subsistemas. Y es mejor no usar arrays y variables globales en absoluto.
Por supuesto, entiendo que es una buena idea utilizar las clases, pero me sigue dando algo de pereza, teniendo en cuenta que es más familiar sin ellas, y que parecen funcionar en cualquier caso. Pero tengo curiosidad, ¿cuál es su ventaja? ¿Si se sabe con certeza que el código está escrito por un autor exclusivamente para sí mismo y que nunca será útil fuera de un programa concreto? Siempre me ha parecido que las clases sólo tienen sentido si escribes para alguien/algo/vendiendo, mientras que para ti mismo como hobby no habrá mucha diferencia. Aparte de la estética y del "más o menos" general, ¿tiene algún sentido práctico meterse en todas estas clases-estructuras? ¿Seguridad? ¿Algo más?
 
Lone_Irbis:
Por supuesto, entiendo que sería bueno para hacer frente a las clases, pero todavía estoy demasiado perezoso, teniendo en cuenta que es más familiar sin ellos, y parecen trabajar de todos modos. Pero tengo curiosidad, ¿cuál es su ventaja? ¿Si se sabe con certeza que el código está escrito por un autor exclusivamente para sí mismo y que nunca será útil fuera de un programa concreto? Siempre me ha parecido que las clases sólo tienen sentido si escribes para alguien/algo/vendiendo, mientras que para ti mismo como hobby no habrá mucha diferencia. Aparte de la estética y del "más o menos" general, ¿tiene algún sentido práctico meterse en todas estas clases-estructuras? ¿Seguridad? ¿Algo más?

Al contrario. Cuando se escribe un proyecto a medida, el cliente suele exigir el código fuente. Y luego hay que sacar funciones de las clases e insertarlas en el código fuente. Es mejor dar al cliente un archivo en lugar de arrastrar una montaña de sus bibliotecas, que contienen un gran número de funciones, que no se utilizan en el trabajo pasado al cliente. Es decir, es mejor utilizar la programación estructurada bajo demanda.

Para sus propias necesidades, es mejor usar OOP - todo es autosuficiente allí y no tiene que molestarse en pasar el código fuente.

 
artmedia70:

Al contrario. Cuando se escribe un proyecto a medida, el cliente suele exigir el código fuente. Y luego hay que sacar funciones de las clases e insertarlas en el código fuente. Es mejor dar al cliente un archivo en lugar de arrastrar una montaña de sus bibliotecas, que contienen un gran número de funciones, que no se utilizan en el trabajo pasado al cliente. Es decir, es mejor utilizar la programación estructurada para un cliente.

Es mejor usar OOP para tus propias necesidades - todo tu material está ahí, y no tienes que molestarte en transferir el código fuente.

Hmmm... Bueno, quizás sí :) Eso es, por supuesto, el principio parece tentador... en teoría. Sobre todo teniendo en cuenta que no puedo hacer un solo archivo sin estructuras ni clases. El caso es que escribo sobre todo por interés, poniendo a prueba mis propias teorías aleatorias e inventando infinitas bicicletas. Paralelamente, sólo estudio lo que empieza a ser necesario para poner en práctica la idea. Todo esto ocurre en el marco de un único Asesor Experto experimental y de aprendizaje - inicialmente un simple martin, pero ahora es más bien un scalper multifuncional en ciernes (y ya teóricamente rentable). Así que, en algún momento, el robot se volvió trivialmente demasiado grande. >.> Cuando la mayor parte del tiempo se pasaba desplazando la rueda del ratón en busca del trozo de código adecuado, tuve la "genial" idea de convertirlo en archivos separados (13 partes conectables por el momento), simplemente agrupando las funciones por su concepto general. Como parser de noticias aquí, procesamiento de niveles allí, otro con controladores de alce, estadísticas por separado, etc. Pero en ese momento mi entusiasmo por tratar con OOP no era suficiente...

Así que mi problema parece ser que estoy cogiendo todas las ideas que se me ocurren y completándolas encima de un robot ya existente de forma bastante... secuencia caótica. El resultado es bastante extraño, con todo tipo de interruptores y combinaciones de modos, muchos de los cuales quedan sin hacer. Todo el cuadro se complementa con ciento cincuenta variables globales, que hay que eliminar de las entradas, para no tardar tanto, quedando impresas en el visualizador del probador al principio. Además, por supuesto, de montañas de basura y rudimentos de ideas abandonadas o rediseñadas.

Y parece que es un buen momento para ordenar todo este montón de basura y poner todo en clases (y antes leer al menos un artículo sobre POO sin quedarse dormido en el proceso)... Pero me confunde la cantidad de trabajo que hay que hacer y, ejem, su relación con el sentido potencial del conjunto. Esto es para concluir todo en clases - parece que no es una tarea tan voluminosa... Pero, ¿tendría sentido, por ejemplo, volcar todo en una fila en la pública, ignorando todas estas privadas/protegidas? ¿Cómo es eso mejor que tener una carpeta con un montón de .mph's y una docena de funciones comunes cada uno, si de todos modos todos terminan en un robot?

 
Lone_Irbis:

Te aconsejo que hagas una plantilla única, que ya tiene todos los pasos necesarios para la inicialización, la conexión, la recogida de los datos siempre necesarios, etc.

Se me ocurrió una idea inesperada: cargar una plantilla, cambiarle el nombre y escribir en ella sólo lo que es relevante para esta idea en particular. Y esas funciones que siempre usas, en cualquier código, devolviendo los mismos datos en cualquier situación - ponlas en clases. Y todo se pondrá en su sitio de inmediato. También puede estructurar los directorios. En \experts\ crear (lo tengo así) la carpeta Pedidos, donde también puse todos los archivos que pertenecen a diferentes clientes en carpetas separadas, hay una carpeta Ideas, Pruebas, etc.

De este modo, podrá mantener el orden.

 
Desgraciadamente, incluso aprendiendo formalmente POO, no podrás construir un programa POO. Más bien hay que adentrarse en la filosofía de este enfoque, y este es el siguiente nivel después de obtener conocimientos formales. Así que resulta, ¿realmente lo necesitas? Pero si te preguntas cómo hacerlo mejor, significa que sientes que la forma que has elegido no es óptima. En cualquier caso, la elección es suya.