Errores, fallos, preguntas - página 1206

 
stringo:

Así es. Se da prioridad a la concurrencia exacta. Y es realmente correcto.

¿Por qué necesita esa unificación? Unificación del procesamiento de programas mal diseñados

La unificación es necesaria para que el mismo código funcione igualmente con C++ y MQL. En C++, este orden se hace (!) por una razón (de lo contrario hay ambigüedades en algún momento). Originalmente pensé que el compilador de C++ tiene ilógica y/o incluso un error, pero ahora me inclino a creer que hay razones objetivas para tal enfoque. Aquí hay un ejemplo en MQL, que muestra que X:: g es una coincidencia completa, pero Y::g se llama de todos modos - como en C++, lo que contradice el ejemplo anterior https://www.mql5.com/ru/forum/1111/page1223#comment_1074757

class A {};
class B : public A {};
class C : public B {};
class X {
public:
        virtual int g( C* c1, C* c2 ) { return ( 1 ); } //полное совпадение здесь
        virtual int g( C* c,  B* b )  { return ( 2 ); }
};
class Y : public C { //здесь ошибся, должно быть public : X
public:
        virtual int g( A* a, B* b ) { return ( 3 ); }
};
void OnStart()
{
        C* c = new C;
        Y* y = new Y;
        Print( y.g( c, c ));
}

Resultado: 3

Resulta que C++ tiene un orden "ilógico" pero inequívoco, mientras que MQL tiene un orden aleatorio - si hay una coincidencia exacta de tipos, se llama a una clase base en un caso y a una clase derivada en el otro

 
A100:

La unificación es necesaria para que el mismo código funcione igualmente con C++ y MQL. En C++, este orden se hace (!) por una razón. Originalmente pensé que el compilador de C++ tiene ilógica y/o incluso un error, pero ahora me inclino a creer que hay una razón objetiva para tal enfoque. Aquí hay un ejemplo en MQL que muestra que X:: g es una coincidencia completa, pero Y::g se llama de todos modos - como en C++, lo que contradice el ejemplo anterior

Resultado: 3

Resulta que C++ tiene un orden "ilógico" pero inequívoco, mientras que MQL tiene un orden aleatorio: cuando los tipos coinciden exactamente, se llama a la clase base en un caso y a la clase derivada en otro.

¿De qué implementación de C++ estás hablando exactamente? ¿En qué medida esta implementación se corresponde con el estándar C++? ¿Qué dice el estándar C++ sobre la elección de funciones sobrecargadas?

En realidad, la sobrecarga de funciones que describes es una consecuencia de un diseño incorrecto.

La portabilidad del código fuente es un mito. Sólo el programa de prueba funciona de la misma manera en diferentes entornos C++. El programa real (estamos hablando de miles de líneas de código con un valor de aplicación real) funcionará de forma diferente al menos en algunos aspectos en diferentes entornos. Y no hay nada que hablar de unificar MQL con C++ en absoluto - es un desperdicio de la reserva genética...

 
A100:

La unificación es necesaria para que el mismo código funcione igualmente con C++ y MQL. En C++, este orden se hace (!) por una razón (de lo contrario hay ambigüedades en algún momento). Originalmente pensé que el compilador de C++ tiene ilógica y/o incluso un error, pero ahora me inclino a creer que hay razones objetivas para tal enfoque. Aquí hay un ejemplo en MQL, que muestra que X:: g es una coincidencia completa, pero Y::g se llama de todos modos - como en C++, lo que contradice el ejemplo anterior https://www.mql5.com/ru/forum/1111/page1223#comment_1074757

Resultado: 3

Resulta que C++ tiene un orden "ilógico" pero no ambiguo y MQL tiene un orden aleatorio - en caso de coincidencia de tipos exacta, una clase base es llamada en un caso y una clase derivada en otro caso

Parece que te equivocas en este ejemplo, si la clase Y se hereda de X y no de C, entonces el comportamiento sería el mismo que en el ejemplo anterior.
 
stringo:

¿Qué dice el estándar C++ sobre el orden de selección de las funciones sobrecargadas?

Citando a Strawstrup: "C++ requiere una coincidencia de tipo exacta entre la función virtual en la clase base y la función sustituida en la clase derivada".

Ahora he investigado el asunto y he llegado a la conclusión de que C++ es correcto. En los dos ejemplos anteriores, g() de la clase derivada oculta (en lugar de sustituir) a g() de la clase base. Y el mecanismo de virtualidad sólo se activa cuando se produce la sustitución, y la sustitución requiere la coincidencia exacta de tipos (excepto el tipo de retorno). Sólo la precisión del tipo de retorno puede depender de la implementación particular.

 
mql5:
Parece que te equivocas en este ejemplo, si la clase Y se hereda de X y no de C, el comportamiento sería el mismo que el del ejemplo anterior.

Sí, aquí me equivoqué, resulta que tanto C++ como MQL tienen órdenes de sustitución y ocultación inequívocas, pero diferentes. Por favor, vea mis argumentos en el post anterior sobre la diferencia entre sustitución y ocultación

El hecho de que C++ genere una advertencia al ocultarse le indica que este orden se elige intencionadamente

class A {};
class B : public A {};

class X {
public:
        virtual int g( A* a )
        virtual int f( B* a )
};
class Y : public X {
public:
        virtual int g( A* a ) //подмена  X::g
        virtual int f( A* a ) //сокрытие X::f
};
 
A100:

Sí, aquí me equivoqué, resulta que tanto C++ como MQL tienen órdenes de sustitución y ocultación inequívocas, pero diferentes. Por favor, vea mis argumentos en el post anterior sobre la diferencia entre sustitución y ocultación

El hecho de que C++ genere una advertencia al ocultar indica que este orden se elige intencionadamente

El compilador de MQL cuando busca un método (función) no considera el paso a un padre como un casting, como parece hacer con C++ de MS, por ejemplo.

Gracias por el post, lo discutiremos.

 
mql5:
El compilador de MQL cuando busca un método (función) no considera el paso a un padre como un casting, como parece hacer con MS C++ por ejemplo.

Gracias por el mensaje, lo discutiremos.

Tenga en cuenta que no sólo de MS - He utilizado Borland C ++ 5.5.1

Stroustrup escribe que, de lo contrario, puede haber consecuencias desagradables relacionadas con "ir más allá del final del objeto de clase"

 
A100:

Citando a Strawstrup: "C++ requiere una coincidencia de tipo exacta entre la función virtual en la clase base y la función sustituida en la clase derivada".

Ahora he investigado el asunto y he llegado a la conclusión de que C++ es correcto. En los dos ejemplos anteriores, g() de la clase derivada oculta (en lugar de sustituir) a g() de la clase base. Y el mecanismo de virtualidad sólo se activa cuando se produce la sustitución, y la sustitución requiere la coincidencia exacta de tipos (excepto el tipo de retorno). Sólo la precisión del tipo de retorno puede depender de la implementación particular.

Espera un minuto, espera un minuto. Estamos hablando de sobrecargar funciones con diferentes parámetros.

Las funciones virtuales, en cambio, siempre tienen parámetros del mismo tipo. Las funciones virtuales quedan fuera del ámbito de esta discusión

 
A100:

Tenga en cuenta que no sólo de MS - He utilizado Borland C ++ 5.5.1

Stroustrup escribe que, de lo contrario, puede haber consecuencias desagradables relacionadas con "sobrepasar el final del objeto de clase"

Ya lo hemos discutido; no vamos a cambiar el comportamiento del compilador MQL - es un "palo de dos filos". Déjeme explicarle.

El problema es relevante sólo cuando se hacen modificaciones en las clases ya hechas (en un programa de trabajo).
Después de que el padre tenga una función más adecuada, el programa dejará de funcionar de repente, porque en lugar del método del descendiente se ha llamado al método del padre.
Bien, si cambiamos el comportamiento de MQL, entonces puede ocurrir una situación similar - al añadir un nuevo método al descendiente, en lugar de la función padre (sin fundición de parámetros) se llama al método descendiente, y con fundición de parámetros, y el programa deja de funcionar de nuevo.

Por lo tanto, no se resolverá ningún problema más que la compatibilidad con C++, además, el cambio del comportamiento del compilador afectará a los programas MQL existentes.
 

Так как переменные типа структур и простых типов не имеют указателей, то применять к ним функцию GetPointer() запрещено.

También está prohibidopasar un punterocomo argumento a una función (¿cuál?¿GetPointer o cualquiera?).En todos estos casos, el compilador informará de un error.

Cita de la documentación.

class A{
public:
   void operator= (const A* from){
      if (GetPointer(this) == GetPointer(from))      // а тут я передаю и все ок
         Alert(1);                                  // резутат 1  из за того что передаю this
      else
         Alert(2);
   }
};

class B : public A{
public:
   void operator= (const B& from){  
      if (GetPointer(this) == GetPointer(from))
         return;
      operator=((A*)(GetPointer(this)));
   }
};
  B b;
   B bb;                        // забыл написать создание объектов и вызов функции.
   b = bb;

Ya he entendido por qué no está regañando por las alertas - es mi culpa que pasé un puntero equivocado en una función.