Errores, fallos, preguntas - página 2357

 
Ilya Malev:

Gracias por la respuesta detallada, sin embargo, no entiendo un poco la lógica.

1) ¿Por qué el compilador percibe la construcción B* b1=a como una llamada al operador de copia A::A(const A&) (y no la llamada B::B(const A&), porque es la clase B la que está 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 A::f() directamente genera un error de compilación "no es una llamada a un método estático")

1) Escribí que este es un error obvio que vamos a arreglar de todos modos

2) el constructor de copia es generado por el compilador, si no es declarado por el usuario

3) la pregunta no está del todo clara.
Por el contexto de la discusión:
Se podría discutir durante mucho tiempo sobre si hay que "desreferenciar" un puntero si no hay acceso a él...
La operación de desreferenciación (obtener el puntero real del handle) es un código "interno" (no personalizado) y caro (comparado con no tenerlo).
¿Por qué realizar la desreferenciación si no habrá acceso al puntero?
Mientras se mantenga así, la operación de desreferenciación es eliminada por el optimizador si no hay acceso al puntero.

 
Ilya Malev:

4) ¿Y por qué el compilador permite una llamada a un método virtual "simple"? No creo que la virtualidad deba depender de la presencia o ausencia de datos en el objeto

Estás confundiendo la cuestión.

La llamada desvirtualización es un método de optimización independiente que no tiene nada que ver con la presencia o ausencia de campos en un objeto.

 
Ilyas:

2) el constructor de copia es generado por el compilador, a menos que sea declarado por el usuario

Hay un objeto B a la izquierda, ¿por qué se llama (o se genera) el constructor A::A(A&) para él? Esto contradice los principios de la POO
 
Alexey Navoykov:
Hay un objeto B a la izquierda, ¿por qué se llama al constructor A::A() para él?

Porque en µl así es como se comportan siempre los operadores =, ==, !=, !&, &| y || cuando hay un puntero a la izquierda y un "objeto" a la derecha. Y al mismo tiempo estos operadores no pueden ser sobrecargados en punteros.

Así que, por favor, cuando arreglen este error, hagan que los operadores anteriores sean sobrecargables para los objetos dinámicos.

 
Metatrader 4 ha dejado de funcionar, funciona durante un segundo más o menos cuando arranco, luego aparece una ventana de negociación de un solo clic en la esquina superior izquierda (Compra/Venta) y luego la aplicación se cierra.
¿Alguna sugerencia sobre cómo solucionarlo?
Gracias de antemano por su ayuda.
 
Ilya Malev:

Porque así es como se comportan siempre los operadores =, ==, !=, !& y || en µl cuando hay un puntero a la izquierda y un "objeto" a la derecha.

¿Qué tiene que ver el puntero? Ya te lo he dicho aquí. Aquí funciona igual sin puntero.
 
Alexey Navoykov:
Hay un objeto B a la izquierda, ¿por qué se llama (o se genera) el constructor A::A(A&) para él? Esto contradice los principios de la POO

Estoy completamente de acuerdo con usted y ya he escrito que se trata de un error que se corregirá.

En este caso, el compilador ha recogido una sobrecarga adecuada en la herencia, que no debería haberse hecho en la construcción del objeto.

 
Ilyas:

Se puede discutir durante mucho tiempo sobre si hay que "desreferenciar" un puntero si no hay acceso a él.

La operación de desreferenciación (obtener un puntero real a partir de un handle) es un código "interno" (no personalizado) y caro (comparado con no tenerlo).
¿Por qué realizar la desreferenciación si no habrá acceso al puntero?

Porque una lista de métodos virtuales es parte de la información de un objeto, no menos importante que los propios datos, y el acceso a los métodos virtuales es un acceso de puntero. Por ejemplo, si escribo en mi ejemplo

  A* aa=a;
  B* b1=a;   
  b1=aa;
  b1.f();

de nuevo obtendré B::f(), aunque este código se refiere explícitamente a la asignación del objeto A*, que fue "copiado" de A y fue referenciado por A*. Esta es una situación más profunda que la de llamar al constructor de copias "equivocado". Pero incluso si el objeto no tuviera ningún método virtual, deberíamos haber comprobado la validez del puntero al acceder a él.

 
Alexey Navoykov:
Hay un objeto B a la izquierda, ¿por qué se llama (o se genera) el constructor A::A(A&) para él ? Esto contradice los principios de la POO

¿Estás seguro de que hay algo llamado allí? Lo he comprobado en x32:

class A {
public:
        A()           { Print(__FUNCSIG__); }
        A( const A& ) { Print(__FUNCSIG__); }
} a;
class B : public A {
public:
        B()           { Print(__FUNCSIG__); }
        B( const B& ) { Print(__FUNCSIG__); }
} *b = a;
void OnStart() {}

Resultado: A::A()
y nada más.

 
A100:

¿Estás seguro de que hay algo llamado allí? Lo he comprobado en x32:

Resultado: A::A()
y nada más.

Así que, a revisar los volcados del generador/optimizador para poner los puntos sobre las íes

Razón de la queja: