Supongamos 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;
};
En teoría, 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.
Debido a que el método Display de la clase Base no es un método virtual, la clase Derived no debería poder anularlo. ¿Derecho?
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 ++.
¿Alguien podría ayudarme con una explicación?
c++
overriding
Leif Lazar
fuente
fuente
de.Base::Display()
.Respuestas:
Sí, estás malinterpretando un poco.
El método del mismo nombre en la clase derivada ocultará el método principal en este caso. Imaginaría que si este no fuera el caso, intentar crear un método con el mismo nombre que un método no virtual de la 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 no ser virtual, no se utilizarán los mecanismos de búsqueda de métodos de C ++ que permitan el polimorfismo. Entonces, por ejemplo, si creó una instancia de su clase derivada pero llamó a su método 'Display' a través de un puntero a la clase base, se llamará al método base, mientras que para 'vDisplay' se llamará al método derivado.
Por ejemplo, intente agregar estas líneas:
... y observe el resultado como se esperaba:
fuente
Sí, has entendido mal un poco:
Funciones virtuales puras:
virtual void fun1()=0
-> debe anularse en la clase derivadaFunciones virtuales:
virtual void fun2()
-> se puede anularFunciones normales:
void fun3()
-> no lo anulePara lograr el polimorfismo en tiempo de ejecución, debe anular las funciones virtuales en c ++
fuente
Creo que también podría ser mejor mirarlo en el contexto de enlace estático vs dinámico.
Si el método no es virtual (ya está por defecto en C ++ a diferencia de Java), entonces el método se une a su llamador en tiempo de compilación, lo que es imposible conocer el objeto real que se apuntará en tiempo de ejecución. Entonces, el tipo de variable es todo lo que importa, que es la 'Base'.
fuente