Preguntas sobre POO en MQL5 - página 44

 
Igor Makanu:

No estoy de acuerdo:

Por favor, actualice sus conocimientos sobre qué son el "operador de asignación" y el "constructor de copia", en qué se diferencian, cuándo y cómo se llaman (explícita e implícitamente).
En el código has resaltado en amarillo el retorno de una variable local desde una función, lo que provoca la llamada al constructor de copia por defecto (no confundir con el operador de asignación).

Lo que es un "tipo de datos completo", por desgracia, no está del todo claro, ni tampoco lo que intentabas demostrar con tu código...
Repito:"eloperador de asignación MQL por defecto devuelve void;"

struct A{
   int x,y;
};

void OnStart(){
   A a, b;
   Print(typename(a = b));   // void
}
 
Koldun Zloy:

No es así.

Sólo tiene que definir su operador=, que devuelve esto, y ver la diferencia.

Puede ver la diferencia cuando el resultado de la asignación se asigna de nuevo.

Si defino operator=, pierdo mi objetivo inicial de llamar a la opción por defecto ::=

Parece una cuestión irresoluble.


Sergey Dzyublik:

Lo que es el "tipo de datos completo", por desgracia, no está muy claro, ni tampoco lo que intentabas demostrar con tu código...

full es full - la estructura de datos se conservará y no hay necesidad de controlar la copia de estructuras si añado nuevos campos

 
Igor Makanu:

Si defino el operador =, me alejo de mi objetivo inicial de llamar a la opción por defecto ::=

¿Realmente necesitas este tipo de tarea?

b = c = a;
 
Igor Makanu:

completo es completo: la estructura de datos se conservará y no es necesario controlar la copia de estructuras si se añaden nuevos campos

Entonces, según su terminología, llamar al operador de asignación por defecto podría dar un "tipo de datos incompleto".
El error de la versión 2019.05.03 nunca se solucionó:https://www.mql5.com/ru/forum/1111/page2451#comment_11556395

 
Koldun Zloy:

¿Realmente necesitas una tarea así?

puramente en teoría, quiero saber si es una "nueva entidad" en lugar de un operador =

No lo necesito para nada para el uso práctico, no tengo problema en ponerlo en 2 operadores


Sergey Dzyublik:

Entonces, según su terminología, llamar al operador de asignación por defecto puede dar un "tipo de datos incompleto".
El error de 2019.05.03 nunca se ha solucionado:https://www.mql5.com/ru/forum/1111/page2451#comment_11556395

"mi terminología" es pedir, sin quejas,

pero el punto de usar el operador por defecto = es que es conveniente describir sólo los campos de la estructura, y todo se copia, incluyendo incluso las dimensiones de los arrays (aunque sólo con dimensiones crecientes - el principio de trabajo es el mismo que en ArrayCopy() )


Bueno, si es un error, debe ser hasta ahora.

 

la cuestión es puramente teórica:

han visto, posiblemente en SB, una llamada al constructor como esta:

class A{
public:   
   A(){Print(__FUNCTION__);}
};

class B{
public:   
   A a1,a2;
   B():a1(),a2() { Print(__FUNCTION__); }   
};

en qué se diferenciaría este código:

class A{
public:   
   A(){Print(__FUNCTION__);}
};

class B{
public:   
   A a1,a2;
   B() { Print(__FUNCTION__); }   
};

Lo he descomprimido, no veo ninguna diferencia, entonces sé un poco más específico - ¿qué o por qué podemos usar una llamada forzada al constructor para los objetos a1 y a2?

¿cuál es la "conveniencia" de la primera opción?

 
Igor Makanu:

la cuestión es puramente teórica:

han visto, posiblemente en SB, una llamada al constructor como esta:

en qué se diferenciaría este código:

Lo he descomprimido, no veo ninguna diferencia, entonces sé un poco más específico - ¿cuál es el beneficio o por qué podemos usar una llamada forzada al constructor para los objetos a1 y a2?

¿cuál es la "conveniencia" de la primera opción?

Los constructores pueden tener parámetros y tienen que ser pasados de alguna manera.

Es decir, hasta que no hay parámetros, no hay diferencia, pero si se utiliza el constructor A(int arg), es otra historia

 
Maxim Kuznetsov:

los constructores tienen parámetros, y deben ser pasados de alguna manera

Es decir, hasta que no hay parámetros, la diferencia es insignificante. Pero si tienes el constructor A(int arg), es una historia diferente

Probablemente tengas razón, depende del objetivo

Sólo tuve dificultades con la primera variante, cuando quise usar 2 constructores de la clase B y recibí código duplicado en ambos constructores - los eliminé, y todo lo que obtuve fue una parte de código que estaba en la primera variante, y surgió la pregunta de dónde lo vi y por qué lo escribí así )))

 
Igor Makanu:

¿qué da o por qué se pueden forzar los constructores de los objetos a1 y a2?

El nombre correcto del proceso no es "llamada forzada al constructor a1 y a2", sino inicialización de los campos de la clase (no estáticos).
Obligatorio en los casos de:

- Uso de campos de clase constantes;
- la ausencia de un constructor por defecto para los campos de la clase;
- ausencia de cualquier otra forma de inicialización de los objetos que no sea a través de la llamada al constructor (por ejemplo, se elimina el operador de asignación);
-...

 

Puede alguien explicar cómo esta inicialización de los campos es mejor que esto:

CArray::CArray(void) : m_step_resize(16),
                       m_data_total(0),
                       m_data_max(0),
                       m_sort_mode(-1)
  {
  }

es mejor que esto:

CArray::CArray(void)
  {
        m_step_resize=16;
        m_data_total=0;
        m_data_max=0;
        m_sort_mode=-1;
  }

¿Y qué sentido tiene?

Razón de la queja: