Discusión sobre el artículo "Usando los punteros de objeto en MQL5"

 

Artículo publicado Usando los punteros de objeto en MQL5:

Por defecto, todos los objetos en MQL5 se pasan por referencia, pero hay una posibilidad de usar los punteros de objeto. Sin embargo, es necesario realizar una comprobación del puntero ya que el objeto puede no ser inicializado. En este caso, el programa MQL5 terminará con un error crítico y descargado. Los objetos, creados automáticamente, no causan este error, por lo que, en esencia, son muy seguros. En este artículo intentaremos comprender la diferencia entre la referencia del objeto y el puntero del mismo y veremos cómo escribir código seguro con el uso de punteros.


 

El código fuente del texto debería ajustarse a los archivos adjuntos, en particular en el listado GetCriticalError_Unsafe.mq5 se hace referencia a la variable inexistente status en lugar de pstatus (como en el archivo).

¿Y qué sentido tiene definir un tipo de variable propio en cada una de las clases sucesoras de CShape?

Y también me gustaría escuchar explicaciones sobre esto. Al pasar del ejemplo GetCriticalError_OnDemand a GetCriticalError_Unsafe, todo el cambio se redujo prácticamente a cambiar el tipo del argumento de la función de CHello *pobject a CHello &pobject. Al mismo tiempo, la llamada a la función no cambiaba: se pasaba un puntero (CHello *). En este caso, según las palabras del autor,"volvemos a obtener un error crítico". La cuestión es que si se pasa un objeto por referencia, el error crítico se produce en la fase de llamada a una función en la que se pasa un objeto no inicializado". Pero en este caso es un puntero y no una referencia lo que se pasa a la función. La cuestión que se plantea es de dónde procede. ¿Podrías explicar las reglas que utiliza MQL5 para la conversión implícita de punteros en referencias y viceversa? O señalar el lugar en la documentación donde se describe. Si el compilador soportara tipado estricto, el ejemplo simplemente fallaría al compilar debido a la falta de una función con un argumento del tipo requerido.

 
marketeer писал(а) # :

El código fuente del texto debería ajustarse a los archivos adjuntos, en particular en el listado GetCriticalError_Unsafe.mq5 se hace referencia a una variable inexistente status en lugar de pstatus (como en el archivo).

Gracias, corregido en el artículo y en el archivo.

 
marketeer писал(а) # :

¿Qué sentido tiene definir su propia variable de tipo en cada una de las clases sucesoras de CShape?

En principio, este miembro no se utiliza en ninguna parte, se puede eliminar. Teóricamente, se puede utilizar en los descendientes para implementar funciones que dependen del tipo de objeto.
 
marketeer писал(а) # :
También me gustaría escuchar algunas aclaraciones sobre este tema. Al pasar del ejemplo GetCriticalError_OnDemand a GetCriticalError_Unsafe, todo el cambio se redujo prácticamente a cambiar el tipo del argumento de la función de CHello *pobject a CHello &pobject. Al mismo tiempo, la llamada a la función no cambiaba: se pasaba un puntero (CHello *). En este caso, según las palabras del autor,"volvemos a obtener un error crítico". Lacuestión es que si se pasa un objeto por referencia, el error crítico se produce en la fase de llamada a una función a la que se pasa un objeto no inicializado". Pero en este caso, se pasa un puntero a la función, no una referencia. La cuestión que se plantea es de dónde procede. ¿Podrías explicar las reglas que utiliza MQL5 para la conversión implícita de punteros en referencias y viceversa? O señalar el lugar en la documentación donde se describe. Si el compilador soportara tipado estricto, el ejemplo simplemente fallaría al compilar porque no hay ninguna función con un argumento del tipo requerido.
Si se define explícitamente una función que acepte un parámetro como puntero, se utilizará. Si no existe tal función, el puntero del objeto se convertirá automáticamente en una referencia al objeto y se utilizará la función que acepte el objeto por referencia.
 
Rosh писал(а) # :
En principio, este miembro no se utiliza en ninguna parte, puede eliminarlo. Teóricamente se puede usar en descendientes para implementar funciones que dependan del tipo del objeto.
Entiendo correctamente que según la fuente actual del ejemplo nos "rastrilla" que en el objeto de una forma de un tipo determinado haya dos variables de tipo, por ejemplo, CLine::type además de CShape::type? Lo ideal sería que hubiera una, de la clase base.
 
Rosh писал(а) # :
Si se define explícitamente una función que acepta un parámetro como puntero, se utilizará. Si no existe tal función, el puntero del objeto se convertirá automáticamente en una referencia al objeto y se utilizará la función que acepte el objeto por referencia.
¿Hay algún sitio donde se pueda leer sobre el sentido de las conversiones implícitas relativas a referencias y punteros? En particular, ¿se realiza también la conversión inversa, de una referencia a un puntero?
 
marketeer писал(а) # :
¿Hay algún sitio donde pueda leer sobre la dirección de las conversiones implícitas realizadas en referencias y punteros? En concreto, ¿se realiza también la conversión inversa, de una referencia a un puntero?
No, para obtener un puntero de objeto, utiliceGetPointer().
Документация по MQL5: Общие функции / GetPointer
Документация по MQL5: Общие функции / GetPointer
  • www.mql5.com
Общие функции / GetPointer - Документация по MQL5
 
marketeer писал(а) # :
¿Entiendo correctamente que según la fuente actual del ejemplo nos "rastrilla" que en el objeto de una forma de un tipo determinado haya dos variables de tipo, por ejemplo, CLine::type además de CShape::type? Lo ideal sería que hubiera una, de la clase base.

Sí, tienes razón. Hay dos variables de tipo en cada descendiente como escribiste. Sucedió así porque se copió el código de los descendientes. Para que un miembro de la clase base esté disponible directamente para los descendientes, debe definirse con el especificador protected o deben declararse métodos públicos get y set para este miembro en la clase base.

Por ejemplo

//+------------------------------------------------------------------+
//|demo_inheritance.mq5
//| Copyright 2010, MetaQuotes Software Corp. | |
//|http://www.mql5.com
//+------------------------------------------------------------------+
#property copyright "2010, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
#property version   "1.00"
//+------------------------------------------------------------------+
//||
//+------------------------------------------------------------------+
class CBase
  {
private:
   int               type;
public:
                     CBase(){type=0;}
   int               GetType(){return(type);}
  };
//+------------------------------------------------------------------+
//||
//+------------------------------------------------------------------+
class CSon: CBase
  {
private:
   int               type;
public:
                     CSon(){type=2;}
   void              PrintType();
  };
//+------------------------------------------------------------------+
//||
//+------------------------------------------------------------------+
void CSon::PrintType()
  {
   Print("CSon.type =",type);
   Print("CBase.type =",CBase::GetType());
  }
//+------------------------------------------------------------------+
//| Función de inicio del programa de script|
//+------------------------------------------------------------------+
void OnStart()
  {
//---
   CSon  son;
   son.PrintType();
   int father_type=son.GetType();
  }
//+------------------------------------------------------------------+
 
Cita:

"Este ejemplo es muy sencillo, no es difícil encontrar un error en él. Pero si tu programa mql5 contiene cientos o incluso miles de líneas, detectar este tipo de errores puede resultar mucho más complicado. Especialmente para aquellos casos en los que las condiciones de situaciones anormales en el comportamiento del programa dependen de factores impredecibles - por ejemplo, en un determinado mercado."

¿Cómo?:-)

 
Es cuando las particularidades de la pareja son diferentes en algún sentido.