c++ override method-overriding function-overriding

c++ - Anulando métodos no virtuales



override method-overriding (3)

Creo que también podría ser mejor verlo en el contexto del enlace estático frente al dinámico.

Si el método no es virtual (ya está predeterminado en C ++ a diferencia de Java), entonces el método se enlaza con el autor de la llamada en el momento de la compilación, lo cual es imposible conocer el objeto real que se apuntará en el tiempo de ejecución. Entonces, el tipo de variable es todo lo que importa, que es la ''Base''.

Asumamos este escenario en Visual C ++ 2010:

#include <iostream> #include <conio.h> using namespace std; class Base { public: int b; void Display() { cout<<"Base: Non-virtual display."<<endl; }; virtual void vDisplay() { cout<<"Base: Virtual display."<<endl; }; }; class Derived : public Base { public: int d; void Display() { cout<<"Derived: Non-virtual display."<<endl; }; virtual void vDisplay() { cout<<"Derived: Virtual display."<<endl; }; }; int main() { Base ba; Derived de; ba.Display(); ba.vDisplay(); de.Display(); de.vDisplay(); _getch(); return 0; };

Teóricamente, la salida de esta pequeña aplicación debería ser:

  • Base: pantalla no virtual.
  • Base: pantalla virtual.
  • Base: pantalla no virtual.
  • Derivado: pantalla virtual.

porque el método de visualización de la clase base no es un método virtual, por lo que la clase derivada no debería poder anularlo. ¿Derecha?

El problema es que cuando ejecuto la aplicación, imprime esto:

  • Base: pantalla no virtual.
  • Base: pantalla virtual.
  • Derivado: pantalla no virtual.
  • Derivado: pantalla virtual.

Entonces, o no entendí el concepto de métodos virtuales o algo extraño sucede en Visual C ++.

¿Podría alguien ayudarme con una explicación?


Sí, estás malinterpretando un poco.

El método del mismo nombre en la clase derivada ocultará el método principal en este caso. Se podría imaginar que si este no fuera el caso, intentar crear un método con el mismo nombre que un método no virtual de clase base debería generar un error. Está permitido y no es un problema, y ​​si llama al método directamente como lo hizo, se considerará correcto.

Pero, al no ser virtual, no se utilizarán los mecanismos de búsqueda de métodos C ++ que permiten el polimorfismo. Así, por ejemplo, si creó una instancia de su clase derivada pero llamó a su método de ''Visualización'' a través de un puntero a la clase base, se llamará al método de la base, mientras que para ''vDisplay'' se llamará al método derivado.

Por ejemplo, intente agregar estas líneas:

Base *b = &ba; b->Display(); b->vDisplay(); b = &de; b->Display(); b->vDisplay();

... y observe la salida como se espera:

Base: pantalla no virtual.
Base: pantalla virtual.
Base: pantalla no virtual.
Derivado: pantalla virtual.


Sí, has malinterpretado un poco:

Funciones virtuales puras:

virtual void fun1()=0 -> debe ser anulado en la clase derivada

Funciones virtuales:

virtual void fun2() -> puede ser anulado

Funciones normales:

void fun3() -> no lo void fun3()

Para lograr el polimorfismo en tiempo de ejecución, debe anular las funciones virtuales en c ++