Anulación de métodos no virtuales

Supongamos este escenario en Visual C ++ 2010:

#include  #include  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, el resultado 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 sobrescribirlo. ¿Derecha?

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

  • Base: pantalla no virtual.
  • Base: pantalla virtual.
  • Derivado: visualización 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 malentendiendo un poco.

El método del mismo nombre en la clase derivada ocultará el método principal en este caso. Imagine que si este no fuera el caso, tratar de crear un método con el mismo nombre que un método no virtual de clase base arrojaría un error. Está permitido y no es un problema, y ​​si llama al método directamente como lo ha hecho, se llamará bien.

Pero, al ser no virtual, no se usarán mecanismos de búsqueda de métodos de C ++ que permitan el polymorphism. Entonces, por ejemplo, si creó una instancia de su clase derivada pero llamó a su método ‘Pantalla’ mediante un puntero a la clase base, se llamará al método base, mientras que para ‘vDisplay’ se invocará el 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 esperaba:

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

Sí, has malentendido un poco:

Funciones virtuales puros:

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 anule

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

Creo que también podría ser mejor mirarlo en el contexto de la vinculación estática vs dinámica.

Si el método no es virtual (ya es por defecto en C ++ a diferencia de Java), el método se une a su llamante en el momento de la comstackción, que es imposible conocer el objeto real que se señalará en el tiempo de ejecución. Entonces, el tipo de variable es lo único que importa, que es la ‘Base’.

    Intereting Posts