OLP. Problemas de aplicación - página 11

 
Interesting:

Qué bueno es poder leer... :)

Tampoco es un mal enfoque, aunque según he entendido ambos enfoques están diseñados para enviar/leer un solo parámetro (aunque de diferentes tipos).

Pero, ¿cómo resolver el problema, cuando tienes muchos parámetros y no puedes ponerlos todos en una clase base?

Según tengo entendido, hay que introducir un índice del parámetro que se pasa (también se puede crear un array en una clase con los parámetros almacenados por índice)...

Yo tampoco lo entiendo...

En mi ejemplo hay un índice, sólo que no es numérico de forma explícita, sino un enum....

 

Olvídalo, no vale la pena.

 

Interesting:

Yedelkin:

En general, tras un debate sobre el problemahttps://www.mql5.com/ru/forum/3566/page6#comment_58280 envió una solicitud a la RE.

1. No lo sé, no lo sé.

No creo que los desarrolladores tomen ciertas medidas, sacrificando la funcionalidad en aras de la seguridad (y con razón por un lado).

Informando.

La aplicación era así:
...

Sugerencia:

1. Aclarar la sección "Polimorfismo" del manual "Polymorphism" en cuanto a la especificación de cómo rellenar correctamente los array shapes[10] con instancias de clases derivadas de CShape (dar un ejemplo).

2. Comprobar si la cadena está escrita correctamente:

CShape[10] shapes;                       // массив объектов CShape

3. Explique si hay que poner o no corchetes inmediatamente después del nombre de la clase que se declara cuando se declaran clases:

clase CShape{};

class CCircle{} :public CShape

class CSquare{} :public CShape

Respuesta:

Rashid Umarov 2011.04.11 15:17

En el momento de redactar la ayuda, algunos puntos aún no estaban claros para la documentación. Arreglaremos este punto y añadiremos el código correcto. Gracias por su mensaje.

Se añadirá una descripción ampliada a la Ayuda, aquí hay un extracto de la misma:

Suponemos que nuestro programa utiliza objetos de diferentes tipos (CCircle y CSquare) pero heredados de un tipo base CShape. El polimorfismo nos permite crear un array de objetos de tipo base CShape, pero cuando declaramos este array, los objetos en sí siguen siendo desconocidos y su tipo es indefinido.

La decisión de qué tipo de objeto contendrá cada elemento del array se tomará durante la ejecución del programa. Esto implica la creación dinámica de objetos para las clases correspondientes y, por tanto, la necesidad de utilizar punteros a objetos en lugar de los propios objetos.

Para crear objetos dinámicamente, se utiliza el operador new; cada uno de estos objetos debe ser eliminado de forma independiente y explícita por el operador delete. Por lo tanto, declararemos un array de punteros de tipo CShape y crearemos un objeto del tipo requerido para cada uno de sus elementos(nuevo_nombre_clase), como se muestra en el script de ejemplo:

//+------------------------------------------------------------------+

//| Script program start function                                    |

//+------------------------------------------------------------------+

void OnStart()

  {

//--- объявим массив указателей объектов базового типа 

   CShape *shapes[5];   // массив указателей на объекты CShape



//--- здесь заполняем массив производными объектами

//--- объявим указатель на объект типа CCircle

   CCircle *circle=new CCircle();

//--- задаем свойства объекта по указателю circle

   circle.SetRadius(2.5);

//--- поместим в shapes[0] значение указателя

   shapes[0]=circle;



//--- создаем еще один объект CCircle и запишем его указатель в shapes[1]

   circle=new CCircle();

   shapes[1]=circle;

   circle.SetRadius(5);



//--- тут мы намеренно "забыли" задать значение для shapes[2]

//circle=new CCircle();

//circle.SetRadius(10);

//shapes[2]=circle;



//--- для неиспользуемого элемента установим значение NULL

   shapes[2]=NULL;



//--- создаем объект CSquare и запишем его указатель в shapes[3]

   CSquare *square=new CSquare();

   square.SetSide(5);

   shapes[3]=square;



//--- создаем объект CSquare и запишем его указатель в shapes[4]

   square=new CSquare();

   square.SetSide(10);

   shapes[4]=square;



//--- массив указателей есть, получим его размер

   int total=ArraySize(shapes);

//--- пройдем в цикле по всем указателям в массиве 

   for(int i=0; i<5;i++)

     {

      //--- если по указанному индексу указатель является валидным

      if(CheckPointer(shapes[i])!=POINTER_INVALID)

        {

         //--- выведем в лог тип и площадь фигуры

         PrintFormat("Объект типа %d имеет площадь %G",

               shapes[i].GetType(),

               shapes[i].GetArea());

        }

      //--- если указатель имеет тип POINTER_INVALID

      else

        {

         //--- сообщим об ошибке

         PrintFormat("Объект shapes[%d] не инициализирован! Его указатель %s",

                     i,EnumToString(CheckPointer(shapes[i])));

        }

     }



//--- мы должны самостоятельно уничтожить все созданные динамические объекты

   for(int i=0;i<total;i++)

     {

      //--- удалять можно только объекты, чей указатель имеет тип POINTER_DYNAMIC

      if(CheckPointer(shapes[i])==POINTER_DYNAMIC)

        {

         //--- сообщим об удалении

         PrintFormat("Удаляем shapes[%d]",i);

         //--- уничтожим объект по его указателю

         delete shapes[i];

        }

     }

  }


Tenga en cuenta que al eliminar un objeto con el operador delete, debe comprobar el tipo de su puntero. Sólo puede eliminar objetos con puntero POINTER_DYNAMIC, obtendrá un error para punteros de otro tipo.

Creo que este ejemplo cubre completamente la idea de crear un array de punteros.
Rashid Umarov 2011.04.11 10:31

Gracias por el post, hemos corregido №2 y №3. Estará en las nuevas versiones de la ayuda



 

Pregunta. La biblioteca estándar utiliza las siguientes líneas

void CTrade::Request(MqlTradeRequest& request) const
  {...}

El Manual de Referencia dice: " el especificador const no es aplicable a los miembros de estructuras y clases". ¿Qué significa el uso de const en un método de la clase anterior y cuáles son las reglas para utilizarlo en estos casos?

Документация по MQL5: Стандартная библиотека
Документация по MQL5: Стандартная библиотека
  • www.mql5.com
Стандартная библиотека - Документация по MQL5
 

Yedelkin:

...............

¿Qué significa el uso anterior de const en un método de clase y cuáles son las reglas para utilizarlo en estos casos?

Oh sí, yo también me lo he preguntado durante mucho tiempo. Quiero utilizar la lengua con sentido, siendo plenamente consciente de las "reglas del juego".
 
Yedelkin:

Pregunta. La biblioteca estándar utiliza las siguientes líneas

El Manual de Referencia dice: " el especificador const no es aplicable a los miembros de estructuras y clases". ¿Qué significa el uso de const en un método de la clase anterior y cuáles son las reglas para utilizarlo en estos casos?

Una cosa es un miembro de una estructura/clase y otra un método.

Un método descrito como const significa que no cambia el estado/miembros de su clase. Es decir, después de llamar a un método de este tipo, el estado interno de la clase permanece inalterado. Se utiliza para indicar adicionalmente al compilador que compruebe los intentos de modificación de los miembros de la clase.

 
Renat:

Una cosa esuna estructura/miembro de clase y otra un método.

Un método descrito como const significa que no cambia el estado/miembros de su clase. Es decir, el estado interno de la clase no cambia después de llamar a este método. Se utiliza para indicar adicionalmente al compilador que compruebe los intentos de modificar los miembros de la clase.

Vaya. Gracias. Y me devané los sesos.

 
TheXpert:
Por cierto, una pregunta lógica ya que estamos en el tema... ¿no hay manual y no se espera?

¿Cómo se puede utilizar? Porque los hilos no interactúan entre sí,

Si los datos pudieran ser transferidos libremente entre hilos, entonces, sí, habría necesidad de tal instrucción.

 
Maldita sea, pensaba que estaba escribiendo algo mal :) ahora ya sé qué. No es volátil, por supuesto, sino mutable:))
 
class COracleTemplate
  {
private:
public:
   string            filename;
                     COracleTemplate(){Init();};
                    ~COracleTemplate(){DeInit();};
   virtual void      Init(){filename=this.Name();Print("loadSettings from ",filename);};
   virtual void      DeInit(){Print("saveSettings to ",filename);};
   virtual string    Name(){return("Prpototype");};
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class CCO2:public COracleTemplate
  {
   virtual string    Name(){return("CO2");};
  };
class CH2O:public COracleTemplate
  {
   virtual string    Name(){return("H2O");};
  };
COracleTemplate* CO2,*H2O;
void OnStart()
  {
   CO2=new CCO2;
   Print(CO2.Name()," filename=",CO2.filename);
   delete CO2;
   
   H2O=new CH2O;
   Print(H2O.Name()," filename=",H2O.filename);
   delete H2O;
   
  }

Buenas tardes.

Una pregunta así.

En el código anterior

¿Qué hice mal o es generalmente inalcanzable en MT5?

Quiero (como creo que es obvio) - obtener nombres anulados en las variables de nombre de archivo...