Errores, fallos, preguntas - página 2356

 
A100:

en C++: A::f()

¿Qué dice este código?

((A*)&b).f();
 
fxsaber:

¿Qué dice este código?

Es lo mismo.

 
Ilya Malev:

Lo mismo.

como MQL (suponiendo que se convierta a la forma C++). Pero podrías haberlo comprobado mismo
 
A100:
Eso y MQL (suponiendo que se convierta en forma de C++). Pero podrías haberlo comprobado mismo

Comprobado:


 
Ilya Malev:

Comprobado:

Creo que estás comprobando algo mal.

B*b1=a;

Tal entrada en MQL significa la copia de un objeto a - a un objeto localizado por el puntero b1. En general, por supuesto, no debe compilar.

Y para no confundir objetos y punteros, es mejor utilizar el prefijo p para los punteros

 
Ilya Malev:

Comprobado:

Por favor, no se dejen embaucar por este comportamiento erróneo.

Hay dos problemas aquí (?):

  1. B *b1=a - un error explícito, el compilador percibe esta construcción como una llamada al operador de copia A::A(const A &).

  2. En el primer caso, el optimizador ha detectado que A::A(const A &) está vacío, sin miembros - no hay acceso por "puntero" (de hecho, no hay código para llamar al operador de copia, todo ha sido recortado)
    la virtual B::f() no está sobrecargada, por lo que en lugar de una llamada virtual era una simple llamada, no hay direccionamiento de miembros en B::f(), por lo que el acceso por "puntero" también fue eliminado

    En el segundo caso, A::f() es un intento de llamada virtual, hay acceso por "puntero", pero no hay objeto a1, porque también se llamó a un constructor de copia vacía A::A(const A &) para A *a1=b
 
Ilyas:

Por favor, no se deje llevar por este comportamiento erróneo.

Hay dos problemas aquí (?):

Espero que arreglen este comportamiento erróneo. (cometer un error de compilación) Porque es posible cometer ese error por accidente y el compilador no reacciona de ninguna manera.

 
Alexey Navoykov:

Espero que arreglen este comportamiento erróneo. Porque es posible cometer ese error por accidente y el compilador no reacciona de ninguna manera.

Sí, lo arreglaremos.

La prioridad es baja porque sólo las clases vacías obtienen código de trabajo

 
Ilyas:

Por favor, no se deje llevar por este comportamiento erróneo.

Hay dos problemas aquí (?):

  1. B *b1=a - un error obvio, el compilador percibe esta construcción como una llamada al operador de copia A::A(const A &)

  2. En el primer caso, el optimizador ha determinado que A::A(const A &) está vacío, sin miembros - no hay acceso por "puntero" (de hecho, no hay código para llamar al operador de copia, todo ha sido cortado)
    la virtual B::f() no está sobrecargada, por lo que en lugar de una llamada virtual era una simple llamada, no hay direccionamiento de miembros en B::f(), por lo que el acceso por "puntero" también fue eliminado

    En el segundo caso, A::f() es un intento de llamada virtual, hay acceso por "puntero", pero no hay objeto a1, porque también se llamó a un constructor de copia vacía A::A(const A &) para A *a1=b

Gracias por la respuesta detallada, sin embargo, estoy un poco confundido con la lógica.

1) ¿Por qué el compilador ve la construcción B* b1=a como una llamada al operador de copia A::A(const A&), (en lugar de llamar a B::B(const A&), porque es la clase B a la izquierda del operador=)

2) ¿Por qué el compilador no ha generado la advertencia "falta el constructor de copia"?

3) por qué se permite una llamada a un método "simple" para objetos inexistentes (mientras que un intento de llamar a B::f() directamente da un error de compilación "no es una llamada a un método estático")

4) ¿Y por qué el compilador permite una llamada a un método virtual "simple"? En mi opinión, la virtualidad no debería depender de la presencia o ausencia de datos en el objeto

 
Ilya Malev:

1) ¿Por qué el compilador ve B* b1=a como una llamada al operador de copia A::A(const A&), (en lugar de llamar a B::B(const A&), porque es la clase B a la izquierda del operador=)

Eso es exactamente correcto. Este es otro error de MQL, que el compilador permite libremente tales cosas: B b = a; Esto es una violación de los principios de encapsulación. En C ++ tales cosas no se compilan de forma natural, una conversión explícita se requiere. Y en las viejas construcciones MQL tales cosas no se podía hacer también.