MQL5 El compilador no distingue entre una clase y un puntero a ella - página 5

 
El signo = copia el área de memoria de un objeto en el área de memoria de otro objeto. Todos los objetos permanecen donde estaban.
 
Vladimir Simakov:
No hay forma de activarlo. Es pura fuga de memoria.

Hazlo de manera que pueda ser invocado.

 

Por cierto, señores desarrolladores, será mejor que arreglemos esto. Al fin y al cabo, new sí devuelve un puntero, así que añade una comprobación de que en el otro extremo = también un puntero, elimina la conversión implícita (A) new A(); según tengo entendido - esto es lo que ocurre.

 
Vladimir Simakov:

Por cierto, queridos desarrolladores, será mejor que arregle esto. Después de todo new realmente devuelve un puntero, así que añade una comprobación de que el otro extremo = también es un puntero, elimina la conversión implícita (A) new A(); como yo lo entendí - esto es lo que sucede.

Hay una llamada para este operador

Foro sobre comercio, sistemas de comercio automatizados y pruebas de estrategias

El compilador MQL5 no distingue entre una clase y un puntero

fxsaber, 2019.01.10 06:36

Desde cuándo están definidos (pregunta para los desarrolladores)

void A::operator =( const A& );
void A::operator =( const A* );

¿Y cómo funcionan? El siguiente código compilado parece delirante

    A* b = NULL;    
    m_A[1] = b;    


A grandes rasgos, tiene el siguiente aspecto

class A
{
public:
    int iValue;
    
    void operator =( const A* Ptr )
    {
      Print(__FUNCSIG__);
      
      this.iValue = Ptr.iValue;
    }
};
//......................
A m_A[2];

void OnStart()
{
A a;

    m_A[0] =a; 
    m_A[1] = new A();
}
 
fxsaber:

Ahí va la llamada a este operador


A grandes rasgos, tiene el siguiente aspecto

Sí, lo entiendo. No es un mal rastrillo. Por cierto, este operador de sobrecarga = no existe en C++, lo jura VS.
 

Antes de hacer un escándalo, sería bueno saber que en MQL toda la vida los punteros han sido lanzados implícitamente a objetos (dereferenciados), es conveniente y todo el mundo se acostumbró a ello. En lugar de la difícil lectura a()->b()->c()->d() se puede escribir en el formato habitual de la POO: a().b().c().d(), y menos transformaciones innecesarias en el proceso de pasar a funciones. ¿Y ahora por el descontento de alguien se cambia todo?

 
Alexey Navoykov:

Antes de hacer un escándalo al respecto, sería bueno saber que en MQL toda la vida los punteros han sido lanzados a objetos implícitamente (dereferenciados), es conveniente y todo el mundo se acostumbró a ello. En lugar de la difícil lectura a()->b()->c()->d() se puede escribir en el formato habitual de la POO: a().b().c().d(), y hacer menos transformaciones innecesarias al pasar a las funciones. ¿Y ahora por el descontento de alguien se cambia todo?

No se trata de un casting. No te has metido en eso.

 

Si nos guiamos por el prototipo declarado de MQL - C++.

En C++, el operador new devuelve un puntero, respectivamente, si m_A es un array de objetos:

m_A[1] = new A();

habría un error de tipo aquí.

Esta es la línea que el compilador habría omitido:

m_A[1] = *( new A() );

Pero provocaría una fuga de memoria.


Sería bueno que MQL tuviera el mismo comportamiento.

 
Alexey Navoykov:

Antes de que empieces a hacer un escándalo por esto, debes saber que en MQL toda la vida los punteros han sido implícitamente lanzados a objetos (dereferenciados), es conveniente y todo el mundo se acostumbró a ello. En lugar de la difícil lectura a()->b()->c()->d() se puede escribir en el formato habitual de la POO: a().b().c().d(), y menos transformaciones innecesarias en el proceso de pasar a funciones. ¿Y ahora por el descontento de alguien se cambia todo?

Y si entramos en detalles con algunos ejemplos sencillos.

A a;

// 'a' ожидает объект
 
a = new A(); // а ему дают указатель, ведь можно же

// что в MQL равнозначно?
a = *(A*) new A();

Como resultado, tenemos

1. a' obtiene una copia del objeto creado, el puntero al nuevo objeto creado se pierde

2. ¿Qué ocurrirá con 'a' si new no consigue crear/asignar un objeto a la memoria?

El segundo caso (por el contrario)

A* a; // глобальный указатель - 'a' ожидает указатель на объект

// далее всё происходит внутри некой функции
A b; // создаем второй в стеке (ну типа в стеке, не суть)

a =b;
// т.е. тут объект "неявно кастится" к указателю?)
a = &b;

1. Después de salir de la función, el objeto 'b' debe ser destruido como objeto local.

¿a qué se referirá entonces "a"?

2. ¿o el operador de copia seguirá funcionando y 'b' será copiado por el puntero 'a'? y si 'a' no ha sido definido antes?

 
SemenTalonov:

El segundo caso (por el contrario)

A* a; // глобальный указатель - 'a' ожидает указатель на объект

// далее всё происходит внутри некой функции
A b; // создаем второй в стеке (ну типа в стеке, не суть)

a =b;
// т.е. тут объект "неявно кастится" к указателю?)


Aquí es al revés - un puntero a es implícitamente fundido a un objeto (dereferenciado) y luego se le aplica operator=. fxsaber también lo mencionó ayer.

Aunque lógicamente no contradice las reglas de MQL (ya que llamar al operador= es equivalente a llamar a cualquier otro método del objeto), lleva a una comprensión ambigua de dicho código y a errores difíciles de encontrar. Y esto se refiere no sólo al operador=, sino también a == y !=. Quizás este tipo de casting debería prohibirse también para otros operadores, ya que en C++ se puede aplicar a los operadores: +-<>[].

El veredicto corto es el siguiente: cuando se aplican operadores permitidos para punteros en C++ a un puntero, no se permite un casting implícito de este puntero a un objeto. En consecuencia, el ejemplo anterior causaría un error de compilación.